2016-02-24 5 views
5

Ich möchte einen String abgleichen, bei dem eine Zahl gleich oder höher als eine Zahl in einer Erfassungsgruppe ist.Kann eine Rückreferenz in einem Nummernbereich verwendet werden?

Beispiel:

  • 1x1 = Spiel
  • 1x2 = Spiel
  • 2x1 = keine Übereinstimmung

In meinem Kopf so etwas wie diese (\d)x[\1-9] die Regex aussehen würde, aber dies nicht Arbeit. Ist es möglich, dies mit Regex zu erreichen?

+3

Was ist der Regex-Geschmack? –

+0

Ich versuche, es in Google Analytics verwenden, die ich nicht sicher bin, was Geschmack ist, aber ich würde PCPRE – Frinsh

+2

annehmen Nein, GA verwendet RE2. Das bedeutet, dass es nicht mit einem reinen Regex möglich ist. –

Antwort

2

Wie Sie entdeckt haben, können Sie in einem regulären Ausdruck, weil ein Wert nicht interpolieren kann:

Weil Charakterklassen bestimmt werden, wenn die Regex kompiliert wird ... Die einzige Art regex Knoten Zeichenklasse ist „Hard- codierte Liste von Zeichen ", die erstellt wurde, als die Regex kompiliert wurde (nicht, nachdem es teilweise gelaufen ist und herausgefunden hat, was $ 1 am Ende sein könnte).

[Source]

Da Charakterklassen Rückreferenzierungen nicht erlauben, ein Schrägstrich gefolgt von einer Zahl in einer Zeichenklasse umgewidmet:

Ein Backslash von zwei oder drei Oktalziffern gefolgt ist als eine Oktalzahl betrachtet.

[Source]

Dies ist offensichtlich nicht das, was Sie von [\1-9] bestimmt. Da es jedoch keine Möglichkeit gibt, eine Zeichenklasse zu kompilieren, bis alle Zeichen bekannt sind, müssen wir einen anderen Weg finden.

Wenn wir dies vollständig in einer Regex tun möchten, können wir nicht alle möglichen Kombinationen aufzählen, da wir alle Captures überprüfen müssen, um herauszufinden, welche Übereinstimmung gefunden wurde. For example:

"1x2" =~ m/(?:(0)x(\d)|(1)x([1-9])|(2)x([2-9])|(3)x([3-9])|(4)x([4-9])|(5)x([5-9])|(6)x([6-9])|(7)x([7-9])|(8)x([89])|(9)x(9))/ 

enthält „1“ in $3 und „2“ in $4, aber Sie würden 1 bis 20 suchen müssen, um finden einfängt, wenn etwas jedes Mal angepasst wurde.


Der einzige Weg, um ist zu tun Nachbearbeitung auf regex Ergebnisse ein regex bedingte zu verwenden: (?(A)X) Wo A eine bedingte und X ist die resultierende Wirkung.

Sadly conditionals are not supported by RE2, aber wir werden weitermachen, nur um zu zeigen, dass es möglich ist.

Was Sie für die X verwenden wollen würde, ist (*F) (oder (?!) in Ruby 2+) Versagen zu erzwingen: http://www.rexegg.com/regex-tricks.html#fail

Was würden Sie für die A verwenden möchten ist ?{$1 > $2}, aber only Perl will allow you to use code directly in a regex.

m/(\d)x(\d)(?(?{$1 > $2})(?!))/ 

[Live Example]

So ist die Antwort auf Ihre Frage lautet: Perl möchten Sie verwenden lassen "Nein, können Sie nicht dies tun, mit RE2, die Google Analytics verwendet, aber ja kann man tun, das mit einem Perl-Regex. "

Verwandte Themen