2016-02-24 10 views
5

Voglio abbinare una stringa in cui un numero è uguale o superiore a un numero in un gruppo di acquisizione.È possibile utilizzare un riferimento posteriore in un intervallo numerico?

Esempio:

  • 1x1 = partita
  • 1x2 = partita
  • 2x1 = alcuna corrispondenza

Nella mia mente l'espressione regolare sarebbe simile a questa (\d)x[\1-9], ma questo non lo fa lavoro. È possibile ottenere questo usando regex?

+3

Qual è il sapore regex? –

+0

Sto cercando di usarlo in google analytics che non sono sicuro di quale sia il sapore, ma suppongo PCPRE – Frinsh

+2

No, GA utilizza RE2. Ciò significa che non è possibile farlo con una regex pura. –

risposta

2

Come hai scoperto, non è possibile interpolare un valore all'interno di un'espressione regolare perché:

Perché classi di personaggi sono determinati quando l'espressione regolare è stato compilato ... Il tipo di nodo regex unica classe di caratteri è "hard- elenco codificato di caratteri "che è stato creato quando è stata compilata la regex (non dopo che è stata eseguita in modo parziale e ha calcolato che cosa potrebbe diventare $ 1).

[Source]

Da classi di caratteri non consentono backreference, una barra rovesciata seguita da un numero viene riproposto in una classe di caratteri:

Un backslash seguito da due o tre cifre ottali è considerato un numero ottale.

[Source]

Questo, ovviamente, non è quello che si intendeva per [\1-9]. Ma dal momento che non c'è modo di compilare una classe di caratteri finché tutti i personaggi non sono noti, dovremo trovare un altro modo.

Se stiamo cercando di fare tutto questo all'interno di una regex, non possiamo enumerare tutte le possibili combinazioni, perché dovremmo controllare tutte le acquisizioni per capire quale corrisponde. 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))/ 

conterrà "1" in $3 e "2" in $4, ma dovreste cercare cattura da 1 a 20 per trovare se qualcosa è stato abbinato di volta in volta.


L'unico modo in giro a fare la post-elaborazione dei risultati regex è quello di utilizzare una regex condizionale: (?(A)X) Dove A è un condizionale e X è l'azione conseguente.

Sadly conditionals are not supported by RE2, ma continueremo ad andare solo per dimostrare che si può fare.

Quello che ci si vuole utilizzare per la X è (*F) (o (?!) in Ruby 2+) per forzare il fallimento: http://www.rexegg.com/regex-tricks.html#fail

Quello che ci si vuole utilizzare per la A è ?{$1 > $2}, ma only Perl will allow you to use code directly in a regex.Perl permetterebbe di utilizzare:

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

[Live Example]

Quindi la risposta alla tua domanda è: "No, non è possibile farlo con RE2 che Google Analytics utilizza, ma sì, si può fare questo con una regex di Perl. "