2016-02-24 10 views
5

Chcę dopasować ciąg znaków, gdy liczba jest równa lub większa od liczby w grupie przechwytywania.Możliwe użycie odniesienia wstecznego w zakresie liczb?

Przykład:

  • 1x1 = mecz
  • 1x2 = mecz
  • 2x1 = brak mecz

W moim umyśle regex będzie wyglądać następująco (\d)x[\1-9] ale to nie praca. Czy można to osiągnąć za pomocą wyrażenia regularnego?

+3

Co to jest smak regex? –

+0

Próbuję użyć go w Google Analytics, którego nie jestem pewien, jaki to smak, ale zakładam PCPRE – Frinsh

+2

Nie, GA używa RE2. Oznacza to, że nie można tego zrobić za pomocą czystego wyrażenia regularnego. –

Odpowiedz

2

Jak odkryłem, nie można interpolować wartość w ciągu regex ponieważ:

Ponieważ klasy postaci są określane podczas regex jest kompilowany ... Jedyna klasa znaków typ węzła regex jest „sprzęt komputerowy zakodowana lista znaków ", która została zbudowana podczas kompilacji regexu (nie po tym, jak przebiegła część drogi i zorientowała się, czym może być 1 $).

[Source]

Od klasy postaci nie pozwalają odwołania wstecznego, backsleshem następuje numer jest repurposed w klasy postaci:

Backslash następnie przez dwie lub trzy cyfry ósemkowe jest uważany za liczbę ósemkową.

[Source]

To oczywiście nie jest to, co zamierzone przez [\1-9]. Ale ponieważ nie ma sposobu na skompilowanie klasy postaci, dopóki wszystkie postaci nie będą znane, będziemy musieli znaleźć inny sposób.

Jeśli chcemy to zrobić w całości w ramach wyrażeń regularnych, nie możemy wyliczyć wszystkich możliwych kombinacji, ponieważ musielibyśmy sprawdzić wszystkie przechwycone dane, aby ustalić, który z nich jest zgodny. 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))/ 

zawierać będzie „1” w $3 i „2” w $4, ale trzeba by szukać rejestruje 1 do 20, aby znaleźć jeśli coś zostało dopasowane za każdym razem.


Jedynym sposobem wokół robi przetwarzanie post na regex wyników jest użycie regex warunkowy: (?(A)X) Gdzie A jest warunkowa i X jest uzyskany działanie.

Sadly conditionals are not supported by RE2, ale będziemy kontynuować, aby zademonstrować, że można to zrobić.

Co tylko chcesz użyć do X jest (*F) (lub (?!) w Ruby 2+), aby wymusić awaria: http://www.rexegg.com/regex-tricks.html#fail

Co tylko chcesz użyć do A jest ?{$1 > $2}, ale only Perl will allow you to use code directly in a regex.Perl pozwoli Ci używać:

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

[Live Example]

Tak więc odpowiedź na to pytanie brzmi: "Nie, nie można tego zrobić z RE2, która korzysta z Google Analytics, ale tak można zrobić to z wyrażeń regularnych Perla. "