Esta expresión regular es de una cadena El?. "canonical" regex es:
modificador
(?s)\{\{wotd\|(.+?)\|(.+?)\|([^#\|]+).*?\}\}
el dotall significa que el punto también puede coincidir con un carácter de nueva línea, pero también lo puede complementado clases de caracteres, al menos con Java: es decir, [^a]
voluntad empareja cada carácter que no es a
, nueva línea incluida. Sin embargo, algunos motores de expresiones regulares NO coinciden con una nueva línea en clases de caracteres complementadas (esto se puede considerar como un error).
El +?
y *?
son cuantificadores perezosos (que generalmente se deben evitar). Significa que tendrán que mirar hacia adelante antes de cada personaje que quieran tragar para ver si este personaje puede satisfacer el siguiente componente de una expresión regular.
El hecho de que {
y }
están precedidos con \
se debe a {...} es el cuantificador de repetición {n, m} donde n y m son números enteros.
Además, es inútil escapar de la tubería |
en la clase de caracteres [^#\|]
, simplemente puede escribirse como [^#|]
.
Y finalmente, .*?
al final parece tragarse el resto de los campos. Una mejor alternativa es utilizar el patrón normal* (special normal*)*
, donde normal
es [^|}]
y special
es \|
.
Aquí está la expresión regular sin usar cuantificadores perezosos, la clase de caracteres "fija" y el extremo modificado. Tenga en cuenta que el modificador dotall ha desaparecido, así, ya que el punto ya no se utiliza:
\{\{wotd\|([^|]+)\|([^|]+)\|([^#|]+)[^|}]*(?:\|[^|}]*)*\}\}
Paso a paso:
\{\{ # 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 "}}"
En la fuente donde se ve esto, es que en una cadena literal ? Por ejemplo, ¿es realmente 'Patrón p = Pattern.compile (" (? S) \\ {\\ {wotd \\ | (. +?) \\ | (¿+?) \\ | ([^ # \\ |] +). *? \\} \\} ");'? Importa, porque las barras invertidas son escapes tanto en cadenas literales como en expresiones regulares, por lo que para interpretar '\\ {' necesitamos saber si eso es '" \\ {"' (en cuyo caso '' \\ 'es visto por el compilador de patrones como una barra diagonal inversa que escapa del siguiente '{') o es '\\ {' (por ejemplo, leer de un archivo de texto o algo así), en cuyo caso el compilador de patrones ve una reacción * escapada * seguida de un ' {'. –
'. +?' Es un operador no codicioso ("renuente") '+'. '\\\' significa una barra invertida literal, suponiendo que la expresión regular es Java y está incrustada en una cadena de Java, la primera '\\' se escapa de la segunda. –