Kennen Sie Ihre Regex-Aromen
Es gibt eine überraschende Anzahl von Menschen, die glauben, dass reguläre Ausdrücke im Wesentlichen sprachunabhängig sind. Tatsächlich gibt es jedoch erhebliche Unterschiede zwischen den Geschmacksrichtungen, und besonders für Codegolf ist es gut, einige davon und ihre interessanten Merkmale zu kennen, damit Sie für jede Aufgabe die beste auswählen können. Hier finden Sie eine Übersicht über einige wichtige Geschmacksrichtungen und was sie von anderen unterscheidet. (Diese Liste kann nicht wirklich vollständig sein, aber lassen Sie mich wissen, wenn ich etwas wirklich Auffälliges verpasst habe.)
Perl und PCRE
Ich werfe diese in einen Topf, da ich mit dem Perl-Geschmack nicht allzu vertraut bin und sie größtenteils gleichwertig sind (PCRE ist schließlich für Perl-kompatible reguläre Ausdrücke). Der Hauptvorteil der Perl-Variante besteht darin, dass Sie Perl-Code tatsächlich aus dem regulären Ausdruck und der Substitution aufrufen können.
- Rekursion / Unterprogramme . Wahrscheinlich das wichtigste Merkmal zum Golfen (das es nur in wenigen Geschmacksrichtungen gibt).
- Bedingte Muster
(?(group)yes|no)
.
- Unterstützt von Fall zu ändern in der Ersatzzeichenfolge mit
\l
, \u
, \L
und \U
.
- PCRE ermöglicht den Wechsel in Lookbehinds, wobei jede Alternative eine andere (aber feste) Länge haben kann. (Die meisten Aromen, einschließlich Perl, erfordern Lookbehinds mit einer festen Gesamtlänge.)
\G
um eine Übereinstimmung mit dem Ende der vorherigen Übereinstimmung zu verankern.
\K
um den Beginn des Spiels zurückzusetzen
- PCRE unterstützt sowohl Unicode-Zeicheneigenschaften als auch Skripte .
\Q...\E
längere Serien von Charakteren zu entkommen. Nützlich, wenn Sie versuchen, eine Zeichenfolge zu finden, die viele Metazeichen enthält.
.NETZ
Dies ist wahrscheinlich der stärkste Geschmack mit nur sehr wenigen Nachteilen.
Ein wichtiges Manko beim Golfen ist, dass es keine Possessive Quantifiers wie einige andere Flavours unterstützt. Stattdessen .?+
musst du schreiben (?>.?)
.
Java
- Aufgrund eines Fehlers (siehe Anhang) unterstützt Java eine begrenzte Art von Lookbehind mit variabler Länge: Sie können bis zum Anfang der Zeichenfolge mit Lookbehind schauen,
.*
von wo aus Sie jetzt einen Lookahead wie starten können (?<=(?=lookahead).*)
.
- Unterstützt Vereinigung und Schnittmenge von Zeichenklassen.
- Bietet die umfassendste Unterstützung für Unicode mit Zeichenklassen für "Unicode-Skripte, -Blöcke, -Kategorien und -Binäreigenschaften" .
\Q...\E
wie in Perl / PCRE.
Rubin
In neueren Versionen ist diese Variante ähnlich leistungsfähig wie PCRE, einschließlich der Unterstützung von Unterprogrammaufrufen. Wie Java unterstützt es auch die Vereinigung und Überschneidung von Zeichenklassen. Eine Besonderheit ist die eingebaute Zeichenklasse für hexadezimale Ziffern: \h
(und die negierte \H
).
Die nützlichste Funktion zum Golfen ist jedoch, wie Ruby mit Quantifizierern umgeht. Insbesondere ist es möglich, Quantifizierer ohne Klammern zu verschachteln. .{5,7}+
funktioniert und funktioniert auch .{3}?
. Im Gegensatz zu den meisten anderen Geschmacksrichtungen kann auf die untere Grenze eines Quantifizierers 0
verzichtet werden, z . B. .{,5}
äquivalent zu .{0,5}
.
Wie für Subroutinen, ist der große Unterschied zwischen PCRE der Subroutinen und Rubys Subroutinen, dass Rubys Syntax ein Byte länger (?n)
vs \g<n>
, aber Rubys Subroutinen können für die Aufnahme verwendet werden, während PCRE Captures nach Unterprogramm beendet zurücksetzt.
Schließlich hat Ruby eine andere Semantik für zeilenbezogene Modifikatoren als die meisten anderen Varianten. Der Modifikator, der normalerweise m
in anderen Geschmacksrichtungen verwendet wird, ist in Ruby immer aktiviert. Also ^
und $
passen Sie immer den Anfang und das Ende einer Zeile an, nicht nur den Anfang und das Ende der Zeichenfolge. Dies kann Ihnen ein Byte ersparen, wenn Sie dieses Verhalten benötigen, aber es kostet Sie zusätzliche Bytes, wenn Sie dies nicht tun, da Sie jeweils ^
und $
durch \A
und ersetzen müssen \z
. Außerdem wird der normalerweise aufgerufene Modifikator s
(der .
Zeilenvorschübe erstellt) m
in Ruby aufgerufen . Dies wirkt sich nicht auf die Anzahl der Bytes aus, sollte jedoch beachtet werden, um Verwirrung zu vermeiden.
Python
Python hat einen soliden Geschmack, aber mir sind keine besonders nützlichen Funktionen bekannt, die Sie sonst nirgendwo finden würden.
Es gibt jedoch eine alternative Variante , die das re
Modul irgendwann ersetzen soll und viele interessante Funktionen enthält. Zusätzlich zur Unterstützung für Rekursion, Lookbehinds variabler Länge und Zeichenklassen-Kombinationsoperatoren verfügt es über die einzigartige Funktion des Fuzzy Matching . Im Wesentlichen können Sie eine Reihe von Fehlern (Einfügungen, Löschungen, Ersetzungen) angeben, die zulässig sind, und die Engine gibt Ihnen auch ungefähre Übereinstimmungen.
ECMAScript
Das ECMAScript-Aroma ist sehr begrenzt und daher zum Golfen selten sehr nützlich. Das Einzige, was es zu tun hat, ist die negierte leere Zeichenklasse [^]
, die mit einem beliebigen Zeichen übereinstimmt, sowie die bedingungslos fehlerhafte leere Zeichenklasse []
(im Gegensatz zu der üblichen (?!)
). Leider weist der Geschmack keine Merkmale auf, was letzteres für normale Probleme nützlich macht.
Lua
Lua hat seinen eigenen, ziemlich einzigartigen Geschmack, der ziemlich begrenzt ist (z. B. kann man nicht einmal Gruppen quantifizieren), aber eine Handvoll nützlicher und interessanter Funktionen enthält.
- Es gibt eine große Anzahl von Abkürzungen für integrierte Zeichenklassen , einschließlich Interpunktion, Groß- / Kleinschreibung und Hexadezimalziffern.
- Damit
%b
wird eine sehr kompakte Syntax unterstützt, um ausgewogene Zeichenfolgen abzugleichen. ZB %b()
entspricht a (
und dann alles bis zu einem Matching )
(korrektes Überspringen innerer Matching- Paare). (
und )
kann hier zwei beliebige Zeichen sein.
Boost
Boosts Regex-Geschmack ist im Wesentlichen Perls. Es hat jedoch einige nette neue Funktionen für die Ersetzung von Regex, einschließlich Falländerungen und Bedingungen . Letzteres gibt es meines Wissens nur bei Boost.