2013-08-14 12 views
5

Se scrivoregex - confuso circa la funzionalità Lookaround

(?<=\()\w+(?=\)) 

per questa stringa: (Test) (Test2) (Test3)

mi metterò: test Test2 Test3

che ha un senso .

Se scrivo

\w+ (?<=\()\w+(?=\)) 

Per questa stringa: LTE (Test)

restituisce nulla .. Qual è il problema?

Spiegare chiaramente la regex poiché può essere difficile da leggere.

+0

utilizzare http://gskinner.com/RegExr/: passa il mouse sopra il codice regex per vedere una spiegazione chiara. Vedi anche http://regex101.com/r/zE8qZ8 – hexicle

+0

ho usato regexr per testare questo in primo luogo. ancora non mi chiarisce perché non funziona – hamobi

risposta

5

I lookaround non consumano caratteri!

Ecco un passo per passo modo di vederlo (potrebbe non essere il migliore, ma è così che io interpreto comunque):

primo carattere è L, il motore regex confronta con \w+ e concorda sul fatto che si tratta di un incontro. Lo stesso accade per T, quindi E.

Nello spazio, il motore regex vede uno spazio nell'espressione regolare, va bene pure.

Il prossimo è il paren di apertura, ma cosa vede la regex? Ricorda che i lookaround non consumano caratteri, in modo che lo \( in (?<=\() non venga effettivamente consumato e \( non corrisponde alle corrispondenze di \w+!

Si potrebbe pensare l'espressione regolare in realtà consumano quei personaggi: \w+ \w+, ma con una condizione sul secondo \w+, che occorre constatare tra parentesi. La condizione potrebbe essere soddisfatta, ma l'espressione stessa non corrisponde a nessuna parentesi!

Per farlo corrispondere, si dovrebbe aggiungere le parentesi:

\w+ \((?<=\()\w+(?=\))\) 

Dopo aver visto e la congruenza lo spazio, il motore regex vede (, che concorda con l'espressione fornita, si muove in avanti.

Il motore vede quindi T. Innanzitutto, corrisponde al carattere successivo, \w+? Sì, secondo, c'è un paren di apertura prima di esso? Sì.

Prima di andare avanti, vede un aspetto positivo. C'è un paren di chiusura poco più avanti? No, c'è e, ma è ancora possibile soddisfare \w+, quindi corrisponde a e con un altro \w. Questo continua così fino al t. Esiste un paren di chiusura dopo lo t? Sì, quindi procedere al controllo successivo.

Si incontra un paren di chiusura, che corrisponde al paren di chiusura nell'espressione (notare che il paren letterale di chiusura potrebbe essere lasciato cadere qui, e invece corrisponderà a LTE (Test).

Ma con tutto ciò, potrebbe essere altrettanto buono per aver lasciato cadere le lookarounds:

\w+ \(\w+\) 

perché aggiungono più a dura prova il motore e, anche se non è così visibile su piccola scala, può essere significativo su una stringa più grande.

Speriamo che aiuti, anche se è un po '!

+0

quindi in sostanza .. un lookaround non può essere davvero utilizzato nel centro di una regex? nel mio primo esempio sto ricevendo tutti i "test" senza parantesie, ma non otterrei l'LTE. Se voglio l'LTE, allora dovrei semplicemente affermare esplicitamente che ci sono delle paraste? Non lo capisco completamente. – hamobi

+0

@hamobi Si _can_ lo si usa al centro di un'espressione regolare, ma se ciò sia utile o meno sarà la domanda. Di solito, cerca di evitarli il più possibile e usali solo se necessario. Di solito richiedono più tempo di elaborazione. – Jerry

2

Lookahead e lookbehind sono "zero-width assertions", non consumano caratteri nella stringa, ma si limitano a stabilire se una corrispondenza è possibile o meno. Il secondo modello tenta di trovare una struttura <word1><space><word2>, ma anche prevede che il numero <word2> sia circondato da parentesi. Non corrisponde a nulla, dal momento che l'unico carattere che accetta prima di <word2> è un <space>! Vorrei semplicemente scrivere le parentesi direttamente nel modello: (\w+) \((\w+)\). L'ho provato e mi dà LTE e Test.

Problemi correlati