2013-06-16 19 views
5

ho questa regex \[.+\]\(.+\)Regex due caratteri speciali di fila

Perché si abbinano questa stringa del tutto?

[test1](test1) thisbitshouldnotmatch [test2](test2) 

Deve corrispondere solo [test1](test1) e [test2](test2). thisbitshouldnotmatch non dovrebbe corrispondere.

+0

Cosa ti fa pensare che debba corrispondere solo a 'test1' e' test2'? –

+0

Scusa, ho formulato la domanda meglio. Penso che le cose tra la seconda parentesi quadra e la prima parentesi tonda non dovrebbero corrispondere. – James

+0

* Off topic *: Se il tuo regex flavor supporta pattern ricorsivi '(? R)' puoi provare quanto segue '(?: \ [(?: [^ [\]] | (? R)) * \] | \ ((?: [^()] | (? R)) * \)) ', questo potrebbe anche corrispondere a stringhe come' [test1 [test11]] (test1 (test11)) '[demo] (http: // regex101 .com/r/uP7kE2). – HamZa

risposta

5

Provare con questa espressione:

\[.+?\]\(.+?\) 

che limiterà il risultato in modo che corrisponda solo la prima occorrenza di [] e di (). Si noti che per impostazione predefinita un'espressione come questa: .+ proverà ad abbinare il più possibile l'input. Aggiungendo un quantificatore ? alla fine: .+?, stiamo specificando che la ricerca dovrebbe fermarsi alla prima corrispondenza trovata.

7

Questo perché l'operatore + è avido.

Per l'espressione \[.+\]\(.+\) i personaggi sono abbinati i seguenti:

[test1](test1) thisbitshouldnotmatch [test2](test2) 
[..........................................](.....) 

modo, corrisponde intero di ingresso!

Avresti bisogno usare sia per nongreedy:

\[.+?\]\(.+?\) 

Oppure, explicitery non consentire alcuni caratteri

\[[^\]]+\]\([^)]+\) 

(notato come ho sostituito il catch-qualsiasi . con un gruppo di caratteri che esclude ] o ) rispettivamente) `

+0

+1 Per il più esplicito '[^ \]]' :) –

4

Hai bisogno di fare il punto pigro altrimenti sarà afferrare tutto il possibile:

\[.+?]\(.+?\) 

O, meglio ancora, utilizzare una classe di caratteri negata, quindi un [ seguita da molti not ] seguito da un ]

\[[^]]++]\([^)]++\) 

si noti inoltre che non è necessario per sfuggire ]

+0

Perdonami la mia ignoranza, ma qual è il significato esatto di '++' qui? "ancora più goloso"? Non penso di aver incontrato nessun operatore '++' prima, in quanto sarebbe essenzialmente lo stesso di '+'. Quale dialetto regolare è quello? – quetzalcoatl

+1

@quetzalcoatl sì, in un certo senso - è _possessive_.Il modo in cui funziona il motore regex è elaborando un carattere alla volta. Se il pattern è avido (come '. *') Il motore prenderà tutto ciò che corrisponde prima a _backtrack_ fino a quando l'intero pattern non coincide. Se il pattern è pigro (come '. *?') Allora il motore prenderà un char alla volta fino a quando l'intero pattern non combacerà. Quindi la distinzione golosa/pigra ha a che fare con _end_ il motore corrisponde. Un modello possessivo afferra tutte le partite e ** mai ** torna indietro. Quindi può essere molto più veloce. –

+0

Disabilitare il backtracking ha molto senso. Lo conosco dal motore .Net/C# Regex (http://msdn.microsoft.com/en-us/library/bs2twtah(v=vs.80).aspx) in forma di operatore '?>' Come in 'a (?> [bc] *) d' e mai visto in forma '++'. Grazie! – quetzalcoatl