2013-06-16 8 views
5

mam tego regex \[.+\]\(.+\)Regex dwa znaki specjalne z rzędu

Dlaczego dopasować ten ciąg całkowicie?

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

Należy tylko dopasować [test1](test1) i [test2](test2). thisbitshouldnotmatch nie powinien się zgadzać.

+0

Co sprawia, że ​​myślisz, że powinno pasować tylko do 'test1' i' test2'? –

+0

Przepraszam, że lepiej sformułowałem to pytanie. Myślę, że materiał pomiędzy drugim kwadratowym wspornikiem a pierwszym okrągłym wspornikiem nie powinien pasować. – James

+0

* Wyłącz temat *: Jeśli Twój smak regex obsługuje wzór rekurencyjny '(? R)' możesz wypróbować następujące rzeczy: (?: \ [(:: [^ [\]] | (? R)) * \] | \ ((?: [^()] | (? R)) * \)) ', to nawet pasuje do ciągów takich jak' [test1 [test11]] (test1 (test11)) '[demo] (http: // regex101 .com/r/uP7kE2). – HamZa

Odpowiedz

5

Spróbuj tego wyrażenia:

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

To ograniczy wynik więc tylko dopasowuje pierwszy wystąpienie [] i (). Zwróć uwagę, że domyślnie takie wyrażenie: .+ będzie próbowało dopasować jak najwięcej danych wejściowych. Po dodaniu kwantyfikatora ? na końcu: .+? określamy, że wyszukiwanie powinno zostać zatrzymane przy pierwszym dopasowaniu, jakie znajdzie.

7

Dzieje się tak, ponieważ operator + to chciwy.

Dla ekspresji \[.+\]\(.+\) znaki są dobrane w sposób następujący:

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

tak, całe wejście pasuje!

trzeba by użyć nongreedy:

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

Albo explicitery odrzucać pewne znaki

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

(zauważ, jak wymieniłem catch-każdy . z grupą postaci, która wyklucza ] lub )) "

+0

+1 Dla bardziej jawnego '[^ \]]' :) –

4

Musisz zrobić kropka leniwy inaczej będzie chwycić wszystko to można:

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

Albo, jeszcze lepiej, użyj zanegowane klasę postaci, więc [ następnie przez wiele not ] następnie ]

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

należy również pamiętać, że nie trzeba uciekać ]

+0

Przebacz mi moją ignorancję, ale jakie jest dokładne znaczenie '++' tutaj? "jeszcze bardziej chciwy"? Nie sądzę, abym wcześniej spotkał się z operatorem '++', ponieważ w zasadzie byłby taki sam jak zwykły '+'. Który dialekt regex to jest? – quetzalcoatl

+1

@quetzalcoatl tak, w pewnym sensie - jest _possessive_.Sposób działania silnika regex polega na przetwarzaniu jednego znaku na raz. Jeśli wzór jest zachłanny (jak '. *'), Silnik pobierze wszystko, co pasuje najpierw, a następnie _backtrack_, dopóki cały wzór nie pasuje. Jeśli wzór jest leniwy (jak '. *?'), Wówczas silnik będzie pobierał po jednym znaku, dopóki cały wzór nie będzie pasował. Tak więc chciwe/leniwy rozróżnienie polega na tym, z którym _end_ silnik pasuje. Dzierżawczy wzór chwyta wszystkie mecze i ** nigdy ** backtracki. Dlatego może być znacznie szybszy. –

+0

Wyłączenie funkcji cofania ma sens. Znam go z .Net/C# Regex engine (http://msdn.microsoft.com/en-us/library/bs2twtah(v=vs.80).aspx) w formie operatora '?>' Jak w 'a (?> [bc] *) d' i nigdy nie widziane w formie '++'. Dzięki! – quetzalcoatl