Da ich für meinen formalen Sprachkurs studiere, bin ich auf diese faszinierenden Beiträge ( One Two ) gestoßen, in denen beschrieben wird, wie man mit einem regulären Ausdruck eine Primzahl findet . Wie gesagt, ein regexp , kein regulärer Ausdruck . Da ein regulärer Ausdruck Strings entspricht durch eine Finite State Automata berechnet und eine Primzahl zu finden , kann nicht von einem FSA erfolgen, die regexp in der Blog - Post gezeigt ist nicht ganz ein regulärer Ausdruck , da es die Zeichenfolge übereinstimmt Rückzieher.
Da ich jetzt nie wirklich einen regulären Ausdruck verwendet habe, meine Frage:
Wie kann ich einen regulären Ausdruck eines "wahren" regulären Ausdrucks sofort erkennen, wenn ich ihn nur betrachte?
Definitionen: Mit regulären Ausdrücken beziehe ich mich auf den Begriff, wie er in formalen Sprachen definiert ist. Mit regulärem Ausdruck meine ich den Begriff, der von modernen Programmiersprachen unterstützt wird. Die Regexp-Syntax enthält häufig zusätzliche Funktionen, z. B. Rückreferenzen. Regexps in Programmiersprachen sind strikt leistungsfähiger als reguläre Ausdrücke im Stil formaler Sprachen.
quelle
Antworten:
tl; dr backrefs.
Sobald sich im
\1
regulären Ausdruck eine (oder eine beliebige Zahl, die nicht zum Entkommen von Unicode verwendet wird) befindet, handelt es sich nicht um einen regulären Ausdruck.Mit Backrefs können Sie festlegen,
(a+)b\1
welche Übereinstimmungen n-mala
gefolgt von b gefolgt von n-mala
für n> 1 übereinstimmen . Dies ist keine reguläre Sprache (es ist das Aushängeschild einer nicht regulären Sprache).Es ist notwendig und nahezu ausreichend, dass die Backref auf eine Gruppe verweist, die einen regulären Ausdruck enthält, der mit einer beliebig langen Zeichenfolge übereinstimmt, oder dass sie ein
*
oder enthält+
. Die einzige Ausnahme (die ich gefunden habe) von einem regulären Ausdruck der Form,(A)B\1
in der A eine endliche Sprache ist (könnte durch eine Aufzählung aller Wörter ersetzt werden, die sie akzeptieren). Sie können es inword1+Bword1|word2+Bword2
usw. konvertieren, da A endlich ist.Look-Around-Gruppen entfernen nicht die Regelmäßigkeit des regulären Ausdrucks.
A(?=B)C
ist der Querschnitt von regulären AusdrückenAB.*
undAC
und der Querschnitt von 2 regulären Sprachen ist regelmäßig. Negativer Lookahead ist ähnlich, außer dass das Komplement von verwendet wirdB.*
(Komplemente regulärer Sprachen sind regulär). Lookbehind ist genau das gleiche wieA(?<=B)C
der Querschnitt vonAC
und.*BC
.quelle
(a)\1
, als ob bei Verwendung eines Backref gleichbedeutendaa
und daher trivial Regular. Ich frage mich auch, ob Lookahead-Behauptungen verwendet werden können, um nicht reguläre Sprachen zu erkennen.(a)\1
ist dies kein regulärer Ausdruck, sondern erkennt eine reguläre Sprache.