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 "}}"
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 '. {'. –
'. +?' 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. –