2013-03-03 16 views
5

Questo modello:Fai un RegEx non avido in direzione contraria a comportarsi allo stesso come in avanti

/a+?b+?/ 

Contro la seguente stringa:

aaaaaabbbbbb 

Partite:

aaaaaab 

Vediamo che il non-avido si comporta in modo diverso nella direzione indietro/sinistra (prende tutto) e avanti/destra (ne prende solo uno).

C'è un modo per rendere il non-goloso all'inizio, che corrisponde a tutti gli a, per abbinare il meno possibile? In modo che si comporti allo stesso modo come con la parte b alla fine?

risposta

1

Essi do comportano lo stesso! Un quantificatore lazy (in questo caso un pigro +) indica al motore regex per

  • inizio alla prima posizione possibile,
  • quindi corrisponde con il minor numero possibile di caratteri (almeno uno in caso di +)
  • ma abbinare il numero necessario per consentire una corrispondenza complessiva.

I regexes corrispondono a "leftwards" o "backwards", come sembra implicare.

Che cosa stai cercando di ottenere? Immagino che non sia questo semplice esempio - sarebbe banale da sistemare (basta fare l'espressione regolare ab, che probabilmente non è quello che stai cercando).

+0

Voglio sapere modo generale su come ottenere il meno possibili corrispondenze sul lato sinistro con il 'a'. Sì, certo questo è solo un esempio. – flori

+1

Puoi fare un esempio che abbia senso? Allora potrebbe essere possibile mostrarti una soluzione significativa. –

+0

@flori: devi in ​​qualche modo rifiutare la corrispondenza 'aaaaaab',' aaaaab', ... 'aab', per abbinare' ab', se questo è quello che vuoi. In questo caso, andrei con 'indexOf (" ab ")'. – nhahtdh

2

I regex corrispondono generalmente da sinistra a destra a meno che non si imposti un flag da destra a sinistra (che supporta pochissimi sapori). In entrambi i casi, non iniziano nel mezzo e poi si allenano in entrambe le direzioni, anche se si utilizza un lookbehind.

Aiuta a fermarsi e chiedere - perché il quantificatore pigro esiste in primo luogo? Che problema intendeva risolvere?

I quantificatori normali (avidi) lavorano trovando un modello di testo corrispondente e quindi ripetutamente facendo corrispondere una sequenza di caratteri fino a quando non possono più corrispondere. Questo comportamento è solitamente desiderato, ma si incontrano problemi quando si ha un modello molto generale seguito da un modello molto specifico in cui il modello specifico è un sottoinsieme del modello generale.

Ad esempio, si consideri il seguente testo:

_abc_END_def_END 

E questo schema:

(\w+END)(\w+END)? 

L'intento, è facile supporre, è quello di abbinare _abc_ e poi END, seguita da _def_ e quindi END. Questa espressione sembrerebbe consentire input in cui il secondo set di caratteri è facoltativo.

Il problema è che END è un sottoinsieme di \w+, quindi la seconda serie è in realtà "consumata" di \w+, con conseguente _abc_END_def_ abbinamento, seguito da END. Questo non è il comportamento desiderato.

La soluzione a questo scenario è modificare il modo in cui il quantificatore si comporta con il modificatore pigro. Questo dà al pattern END la possibilità di abbinarlo con ciascun carattere e consente allo \w+ di consumare un altro carattere solo se END fallisce.

Lo scopo del quantificatore pigro non è quello di abbinare un numero "minimo" di caratteri - si tratta di dare a quel secondo modello, un sottoinsieme del primo, un'opportunità di corrispondenza.

Nel tuo esempio, b non è un sottoinsieme di a, quindi non è necessario il quantificatore pigro. Se si desidera far corrispondere uno o più di un di, ma il meno possibile, e uno o più b è, ma il meno possibile, allora si sarebbe sufficiente utilizzare:

ab 

Oppure, se il vostro a è uno stand -in per qualche sovrainsieme che possono includere b:

[ab]b 

Ad esempio:

\wb 

Entrambi che corrisponderebbe:

ab 
1

Se non si ha la capacità di eseguire la corrispondenza da destra a sinistra precedentemente menzionata, è possibile semplicemente invertire la stringa, invertire l'espressione regolare, quindi invertire il risultato alla fine.

Il lavoro è la seguente:

Start with aaaaaabbbbbb 
Reverse to bbbbbbaaaaaa 
Reverse /a+?b+?/ to /b+?a+?/ 
The resulting Match is bbbbbba 
Reverse the resulting match to get abbbbbb 
Problemi correlati