2016-10-04 3 views
4

übereinstimmen Grundsätzlich brauche ich eine Kombination von \k und \g. HierGleiche Anzahl von Zeichen wie durch vorherige Gruppe

ist ein Beispiel:

ich Strings in Form von "123045 ; 67089" haben. Ich muss dies nur dann tun, wenn sich in beiden Zahlen an derselben Stelle eine repetierende Ziffer in Bezug auf das Ende der Zahl befindet. In diesem Fall ist die 0 in 123045 zwei Positionen vom Ende der Nummer entfernt, wie es die 0 in 67089 ist.


Das Problem ist, dass, wenn ich Rückreferenzierungen verwenden, werden die gesamten Reste der Zahlen übereinstimmen müssen (aka 45 mit 89):

^\d*(\d)(\d*) ; \d*\1\2$ 

Und wenn ich Muster erneuten Ausführung verwenden, muss ich geben bestimmte Anzahl von Zeichen verbleibend (in diesem Fall - zwei):

^\d*(\d)(\d{2}) ; \d*\1\g<2>$ 

Ja, es muss in einem einzigen Regex sein.

+0

nur einen sehr schnellen Schuss, nicht sicher, ob Rubin unterstützt PCRE vollständig und nicht getestet vollständig finden: https://regex101.com/r/u0ZBdR/3 –

+1

@SebastianProske: Rubin Regex läuft auf Onigmo, nicht PCRE. Es unterstützt Rekursion mit Hilfe von '\ g ' Notation. Verwenden Sie [Rubular] (http://rubular.com), um Ruby-Regex-Muster zu testen. –

+0

@SebastianProske, das ist schlau, ich hätte an so etwas denken sollen. Auch wenn es keine ungültigen Eingaben verarbeitet, aber optimiert werden kann. Schreibe das als Antwort (ersetze einfach '(? 2)' durch '\ g <2>'). – ndn

Antwort

3

Was Sie hier vor sich haben, ist ein Balance-Problem. Sie Rekursion es lösen können, dann wäre mein Ansatz:

^\d*(\d)(?:(\d(?:(\s*;\s*\d*\1)|\g<2>)\d)|\g<3>)$ 

Diese \s*;\s*\d*\1 als Inhalt zwischen zwei symmetrischen Gruppen von Zahlen nehmen. Um die Rekursion zu verlassen, muss dieser Inhalt genau einmal verglichen werden (um Übereinstimmungen wie 122 oder 12;1;13 zu vermeiden). Die Rekursion zu diesem Inhalt als eine Alternation ist für den Fall, dass die verdoppelte Ziffer die letzte jeder Zahl ist.

Sie einige Testfälle here

Verwandte Themen