2010-07-14 11 views
7

Giocando con le espressioni regolari, in particolare l'abbinamento bilanciato del sapore .NET, sono arrivato a un punto in cui mi sono reso conto che non capivo i meccanismi interni del motore come pensavo di fare. Apprezzerei qualsiasi input sul perché i miei schemi si comportano come fanno loro! Ma pugno ...In che modo i condizionali nei gruppi di ricerca funzionano in regex .NET?

Declinazione di responsabilità: Questa domanda è puramente teorica e qualsiasi risultato ottenuto qui non verrà mai utilizzato, né modificato e utilizzato nel codice di produzione per analizzare HTML. Mai. Lo prometto. Ho paura del pony. =)

Ora per il mio problema. Proverò ad abbinare la lettera A, se non è preceduta da un #. Per dimostrare, userò sempre la stringa ..A..#..A... Qui, il primo A deve corrispondere. Ovviamente, questo è un compito abbastanza semplice usando "A(?<!^.*#.*)", ma qui desidero utilizzare i condizionali, poiché possono essere utilizzati per corrispondenze bilanciate e altre cose interessanti.

Quello che ho cercato è

"A(?<=^(#(?<q>)|[^#])*(?(q)(?!)))" 

Il modo in cui io interpreto è: quando il motore encounteres una "A", si va indietro all'inizio della stringa, e per ogni personaggio aggiungere delle partite vuota il gruppo che cattura q se il personaggio è un #. Quindi dovrebbe fallire se q contiene una corrispondenza. Quello che non capisco è il motivo per cui questa espressione corrisponde sia come nella mia stringa di esempio.

Quando mi è sufficiente rimuovere il lookbehind e Match l'intera stringa, questo funziona:

"^(#(?<q>)|[^#])*(?(q)(?!))A" 

corrisponde l'intera stringa fino al primo A, anche se quantificatore del primo gruppo è avido. L'inserimento di un "#" all'inizio causerà anche il fallimento della corrispondenza (come desiderato).

Quindi: come si guardano attorno i gruppi, i gruppi di cattura denominati al loro interno e le condizioni condizionali giocano insieme?

Grazie!

Modifica: Questo problema può essere visualizzato più facilmente in (?<=(?<q>)(?(q)(?!)))., che non deve corrispondere a nessun carattere, ma corrisponde a tutto.

+0

+1 e ho ricevuto solo per secondo comma finora./Ok, leggi il tutto, ma troppo male questo è molto specifico per C# e non posso contribuire ... ANCORA! Domanda preferita e segnalibro! – polygenelubricants

+0

@polygenelubrificanti: Hehe, grazie! =) – Jens

risposta

3

Le condizioni non sono davvero così utili per la corrispondenza bilanciata - o altrove, se è per questo. ;) La corrispondenza bilanciata funziona utilizzando un gruppo di cattura denominato come una pila; ogni volta che quel gruppo corrisponde a qualcosa, il testo abbinato viene inserito nello stack. C'è anche una sintassi speciale per schioccare lo stack. Ecco una buona introduzione:

http://blog.stevenlevithan.com/archives/balancing-groups

+0

In realtà ho affrontato questo problema quando provavo a utilizzare prima la corrispondenza bilanciata. Questa tecnica sembra fallire se usata in un lookbehind, e non ho idea del perché. Questa domanda è il caso più semplice in cui si può vedere lo stesso fallimento. – Jens