2013-08-14 16 views
5

Wenn ich schreiberegex - verwirrt über Lookarounds Funktionalität

(?<=\()\w+(?=\)) 

für diesen String: (Test) (Test2) (Test3)

I erhalten: Test Test2 Test3

Das macht Sinn .

Wenn ich

\w+ (?<=\()\w+(?=\)) 

für diesen String schreiben: LTE (Test)

es gibt nichts zurück .. Was ist das Problem hier ist?

Bitte erläutern Sie Ihre Regex klar, da es schwer zu lesen sein kann.

+0

Verwenden Sie http://gskinner.com/RegExr/: Fahren Sie mit der Maus über Ihren Regex-Code, um eine klare Erklärung zu erhalten. Siehe auch http://regex101.com/r/zE8qZ8 – hexicle

+0

Ich habe Regexr verwendet, um dies an erster Stelle zu testen. macht mir immer noch nicht klar, warum es nicht funktioniert – hamobi

Antwort

5

Lookarounds konsumieren keine Zeichen!

Hier ist ein Schritt für Schritt Weg, es zu sehen (vielleicht nicht die besten sein, aber das ist, wie ich es sowieso interpretieren):

Die erste Zeichen ist L, die Regex-Engine mit \w+ vergleicht und stimmt zu, dass es eine ist Spiel. Gleiches passiert für T, dann E.

An der Stelle, die Regex-Engine sieht ein Leerzeichen im regulären Ausdruck, das ist auch in Ordnung.

Als nächstes ist die Öffnung paren, aber was sieht die Regex? Denken Sie daran, dass Lookarounds keine Zeichen konsumieren, so dass die \( in (?<=\() nicht tatsächlich konsumiert wird und \( nicht übereinstimmt, was \w+ entspricht!

Sie könnten darüber nachdenken, dass die Regex tatsächlich diese Zeichen verbraucht: \w+ \w+, aber mit einer Bedingung auf der zweiten \w+, dass es zwischen Parens gefunden werden muss. Die Bedingung ist möglicherweise erfüllt, aber der Ausdruck selbst passt nicht zu Klammern!

Um es zu passen, können Sie die Pars hinzufügen sollte:

\w+ \((?<=\()\w+(?=\))\) 

Nach der Besichtigung und Anpassung der Raum, sieht die Regex-Engine (, die mit dem angegebenen Ausdruck übereinstimmt, es nach vorne bewegt.

Der Motor sieht dann T. Passt es zuerst zum nächsten Zeichen, \w+? Ja, zweitens, gibt es davor eine Öffnung? Ja.

Bevor wir fortfahren, sieht es eine positive Vorausschau. Gibt es einen abschließenden Paren gerade vor? Nein, es gibt e, aber \w+ kann immer noch erfüllt werden, also passt es e mit einem anderen \w. Dies geht so weiter bis t. Gibt es eine Schließung nach t? Ja, fahren Sie mit der nächsten Überprüfung fort.

Es trifft auf einen schließenden paren, der mit dem schließenden paren im Ausdruck übereinstimmt (beachten Sie, dass der literale schließende Buchstabe hier weggelassen werden könnte und Sie stattdessen LTE (Test entsprechen).

Aber mit all dem könnte es genauso gut sein, um die lookarounds fallen gelassen zu haben:

\w+ \(\w+\) 

Weil sie mehr Belastung für den Motor hinzufügen und auch wenn es nicht so sichtbar in kleinem Maßstab, kann es sein, signifikant auf einer größeren Saite.

Hoffentlich hilft es, auch wenn es ein bisschen ist!

+0

so im Grunde .. ein Lookaround kann nicht wirklich in der Mitte eines Regex verwendet werden? In meinem ersten Beispiel bekomme ich alle "Tests" ohne Klammern, aber ich würde das LTE nicht bekommen. Wenn ich das LTE möchte, dann sollte ich nur explizit sagen, dass es Klammern gibt? Ich verstehe es nicht ganz. – hamobi

+0

@hamobi Sie können es in der Mitte einer Regex verwenden, aber ob das nützlich ist oder nicht, wird die Frage sein. Normalerweise versuchen Sie, sie so weit wie möglich zu vermeiden, und verwenden Sie sie nur bei Bedarf. Sie benötigen normalerweise mehr Bearbeitungszeit. – Jerry

2

Lookahead und Lookbehind sind "zero-width assertions", sie konsumieren keine Zeichen in der Zeichenfolge, sondern nur, ob eine Übereinstimmung möglich ist oder nicht. Ihr zweites Muster versucht, eine <word1><space><word2> Struktur zu finden, aber es auch erwartet, dass <word2> von Klammern umgeben ist. Es wird auf nichts passen, da das einzige Zeichen, das es vor <word2> annimmt, ein <space> ist! Ich würde einfach die Klammern direkt in das Muster schreiben: . Ich habe es versucht, und es gibt mir LTE und Test.