regex - positive - ¿Cómo funciona la expresión regular ''(?<=#)[^#]+(?=#)''?
regex one (3)
Como se menciona en otro póster, se trata de regular-expressions.info/Lookarounds , construcciones especiales para cambiar lo que coincide y cuándo. Esto dice:
(?<=#) match but don''t capture, the string `#`
when followed by the next expression
[^#]+ one or more characters that are not `#`, and
(?=#) match but don''t capture, the string `#`
when preceded by the last expression
Entonces esto coincidirá con todos los personajes entre dos # s.
Lookaheads y lookbehinds son muy útiles en muchos casos. Considere, por ejemplo, la regla "unir todas las b s no seguidas por una a ". Tu primer intento podría ser algo así como b[^a] , pero eso no está bien: esto también coincidirá con el bu en bus o el bo en boy , pero solo querías el b . Y no coincidirá con el b en la cab , aunque eso no sea seguido por una a , porque no hay más personajes para unir.
Para hacerlo correctamente, necesita un vistazo: b(?!a) . Esto dice "coincide con una b pero no coincide con una a después, y no hagas esa parte del partido". Por lo tanto, coincidirá solo con el b en bolo , que es lo que quieres; también coincidirá con el b en la cab .
Tengo la siguiente expresión regular en un programa de C #, y tengo dificultades para entenderlo:
(?<=#)[^#]+(?=#)
Lo dividiré en lo que creo que entendí:
(?<=#) a group, matching a hash. what''s `?<=`?
[^#]+ one or more non-hashes (used to achieve non-greediness)
(?=#) another group, matching a hash. what''s the `?=`?
Entonces el problema que tengo es la parte ?<= Y ?< . Al leer MSDN,? ?<name> se usa para nombrar grupos, pero en este caso el corchete angular nunca se cierra.
No pude encontrar ?= En los documentos, y su búsqueda es realmente difícil, porque los motores de búsqueda ignorarán en su mayoría esos caracteres especiales.
Se llaman " look-arounds" : regular-expressions.info/Lookarounds
Se llaman "Miradores"; te permiten afirmar si un patrón coincide o no, sin llegar a hacer la coincidencia. Hay 4 orientaciones básicas:
- Miradas positivas: vea si PODEMOS coincidir con el
pattern...-
(?=pattern)- ... a la derecha de la posición actual (mirar hacia adelante ) -
(?<=pattern)- ... a la izquierda de la posición actual (mira hacia atrás )
-
- Miradas negativas: vea si NO podemos igualar el
pattern-
(?!pattern)- ... a la derecha -
(?<!pattern)- ... a la izquierda
-
Como recordatorio fácil, para un vistazo:
-
=es positivo!es negativo -
<está atrás , de lo contrario es mirar hacia adelante
Referencias
Pero, ¿por qué usar lookarounds?
Se podría argumentar que las aproximaciones en el patrón anterior no son necesarias, y #([^#]+)# hará el trabajo bien (extrayendo la cadena capturada por /1 para obtener el valor no # ).
No exactamente. La diferencia es que dado que un vistazo no coincide con el # , se puede "usar" nuevamente en el próximo intento de encontrar una coincidencia. Simplificando hablando, las alternativas permiten que las "coincidencias" se superpongan.
Considere la siguiente cadena de entrada:
and #one# and #two# and #three#four#
Ahora, #([az]+)# dará las siguientes coincidencias ( como se ve en rubular.com ):
and #one# and #two# and #three#four#
/___/ /___/ /_____/
Compare esto con (?<=#)[az]+(?=#) , Que coincide con:
and #one# and #two# and #three#four#
/_/ /_/ /___/ /__/
Lamentablemente, esto no se puede demostrar en rubular.com, ya que no es compatible con lookbehind. Sin embargo, es compatible con la búsqueda anticipada, por lo que podemos hacer algo similar con #([az]+)(?=#) , Que coincide ( como se ve en rubular.com ):
and #one# and #two# and #three#four#
/__/ /__/ /____//___/