¿Cómo funciona la expresión regular ‘(? <= #) + (? = #)'?

Tengo la siguiente expresión regular en un progtwig 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,? ? 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 “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
    • (? - ... 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

  • regular-expressions.info/Lookarounds

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 bash 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# \__/ \__/ \____/\___/ 

Referencias

  • regular-expressions.info/Flavor comparación

Como se menciona en otro póster, se trata de aproximaciones , 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 bash 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 .

Se llaman ” look-arounds” : http://www.regular-expressions.info/lookaround.html

    Intereting Posts