2012-01-08 11 views
5

Próbuję zrozumieć ten regex, możesz mi pomóc?regex, którego nie rozumiem

(?s)\\{\\{wotd\\|(.+?)\\|(.+?)\\|([^#\\|]+).*?\\}\\} 
  • ja nie bardzo rozumiem sens dotall: (?s)
  • dlaczego podwójnie \\ przed }?
  • co to dokładnie znaczy: (.+?) (powinniśmy przeczytać jak: the ., następnie + działając na ., następnie ? odpowiada wynikowi .+
+4

w źródle, gdzie można zobaczyć to, czy to w dosłownym sznurku ? Np. Czy to naprawdę 'Wzór p = Wzór.Kompiluj (" (? S) \\ {\\ {wotd \\ | (. +?) \\ | (. +?) \\ | ([^ # \\ |] +). *? \\} \\} ");'? Ma to znaczenie, ponieważ ukośniki odwrotne są ucieczkami zarówno w literałach łańcuchowych, jak iw wyrażeniach regularnych, więc aby zinterpretować '\\ {' musimy wiedzieć, czy to jest '\\ {" (w którym to przypadku '\\' jest widziane przez kompilator wzorca jako pojedynczy ukośnik odwrotny, który wymyka się następującemu '{') lub '\\ {' (np. czytając z pliku tekstowego lub czegoś podobnego), w którym to przypadku kompilator wzorca widzi * cofnięcie * luzu, po którym następuje '. {'. –

+0

'. +?' Nie jest chciwym ("niechętnym") operatorem '+'. '\\\' oznacza dosłowny ukośnik odwrotny, przy założeniu, że regex to Java i osadzony w łańcuchu Java, pierwsze '\\' ucieka drugie. –

Odpowiedz

8

Ten regex jest z ciągiem przycisk?. „kanoniczny” regex jest:

(?s)\{\{wotd\|(.+?)\|(.+?)\|([^#\|]+).*?\}\} 

dotall modyfikator oznacza, że ​​kropka można również dopasować znak nowej linii, ale tak może uzupełnione klas postaci, przynajmniej w Javie: tj [^a] będzie dopasuj każdy znak, który nie jest a, zawiera znak nowej linii. Niektóre silniki wyrażeń regularnych NIE pasują do znaku nowej linii w uzupełnianych klasach znaków (można to uznać za błąd).

Jednostki +? i *? to leniwy kwantyfikator (na ogół należy go unikać). Oznacza to, że będą musieli patrzeć przed każdą postacią, którą chcą połknąć, aby sprawdzić, czy ta postać może zaspokoić następny składnik regexu.

Fakt { i } poprzedza \, ponieważ {...} jest kwantyfikatorem powtórzenie {n, m}, gdzie n i m są liczbami całkowitymi.

Poza tym nie ma sensu uciekać z rury | w klasie znaków [^#\|], można ją napisać po prostu jako [^#|].

I na koniec, .*? na końcu wydaje się połykać resztę pól. Lepszą alternatywą jest użycie wzoru normal* (special normal*)*, gdzie normal jest [^|}] i special jest \|.

Tutaj jest wyrażenie regularne bez użycia leniwych kwantyfikatorów, "ustalonej" klasy znaków i zmodyfikowanego końca. Zauważ, że modyfikator dotall zniknął, jak również, ponieważ kropka nie jest już używany:

\{\{wotd\|([^|]+)\|([^|]+)\|([^#|]+)[^|}]*(?:\|[^|}]*)*\}\} 

Krok po kroku:

\{\{   # literal "{{", followed by 
wotd   # literal "wotd", followed by 
\|   # literal "|", followed by 
([^|]+)  # one or more characters which are not a "|" (captured), followed by 
\|   # literal "|", followed by 
([^|]+)  # one or more characters which are not a "|" (captured), followed by 
\|   # literal "|", followed by 
([^#|]+)  # one or more characters which are not "|" or "#", followed by 
[^|}]*  # zero or more characters which are not "|" or "}", followed by 
(?:   # begin group 
    \|   # a literal "|", followed by 
    [^|}]*  # zero or more characters which are not "|" or "}" 
)   # end group 
*   # zero or more times, followed by 
\}\}   # literal "}}" 
+0

Dlaczego sugerujesz unikać leniwych kwantyfikatorów? – Lucero

+0

Należy zauważyć, że twoje wyrażenie regularne nie jest równoważne z oryginałem; oryginał będzie pasował do wielu ciągów, których twój nie będzie. Gdybym miał zgadywać, domyślałbym się, że twoja wersja jest bliżej pierwotnej intencji regex-piszącego, ale nie wiedząc, jakie są wymagania, nie ma możliwości, by wiedzieć na pewno. (A tak przy okazji, możesz równie dobrze usunąć '(? S)' ze swojej wersji, ponieważ twoja wersja nie używa '.' tak czy inaczej.) – ruakh

+0

Żadne końcowe'. *? 'Nie ma znaczenia, ponieważ inne rury również są zbieżne (co obniża twoje ostatnie wyliczenie). Wyrażenie regularne szuka ciągu, w którym potok jest używany jako separator pól sortowania: '{wotd | field1 | field2 | some_stuff # być może komentarz?}' – user268396