¿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