¿Para qué sirve el ancla ‘\ G’ en expresiones regulares?

Tengo dificultades para entender cómo funciona el anclaje \G en el sabor PHP de las expresiones regulares.

Me inclino a pensar (aunque puedo estar equivocado) que \G se usa en lugar de ^ en situaciones en las que se producen varias coincidencias de la misma cadena.

¿Podría alguien mostrar un ejemplo de cómo debería usarse \G y explicar cómo y por qué funciona?

ACTUALIZAR

\ G fuerza al patrón a devolver solo coincidencias que forman parte de una cadena continua de coincidencias. Desde el primer partido, cada encuentro subsiguiente debe ir precedido de un partido. Si rompes la cadena, las coincidencias terminan.

 '; } echo '
'; $pattern = '#(\Gmatch),#'; $subject = "match,match,match,match,not-match,match"; preg_match_all( $pattern, $subject, $matches ); //Will only output match 4 times because at not-match the chain is broken foreach ( $matches[1] as $match ) { echo $match . '
'; } ?>

Esto es directo de los documentos

El cuarto uso de la barra invertida es para ciertas aserciones simples. Una aserción especifica una condición que debe cumplirse en un punto particular de una coincidencia, sin consumir ningún carácter de la cadena del sujeto. El uso de subpatrones para afirmaciones más complicadas se describe a continuación. Las aserciones de barra invertida son

  \G first matching position in subject 

La aserción \ G solo es verdadera cuando la posición de coincidencia actual está en el punto de inicio de la coincidencia, tal como lo especifica el argumento de compensación de preg_match (). Difiere de \ A cuando el valor de compensación no es cero.

http://www.php.net/manual/en/regexp.reference.escape.php

Tendrá que desplazarse un poco hacia abajo en esa página, pero allí está.

Hay un buen ejemplo en ruby, pero es lo mismo en php.

¿Cómo funciona Anchor \ z y \ G en Ruby?

\G coincidirá con el límite de coincidencia, que es el comienzo de la cadena o el punto donde se consume el último carácter de la última coincidencia.

Es particularmente útil cuando necesita realizar tokenización compleja, al tiempo que se asegura de que los tokens sean válidos.

Problema de ejemplo

Tomemos el ejemplo de tokenizar esta entrada:

 input 'some input in quote' more input '\'escaped quote\'' lots@_$of_fun ' \' \\ ' crazy'stuff' 

En estos tokens (uso ~ para denotar el final de la cadena):

 input~ some input in quote~ more~ input~ 'escaped quote'~ lots@_$of_fun~ ' \ ~ crazy~ stuff~ 

La cadena consiste en una mezcla de:

  • Cadena singularmente citada, que permite el escape de \ y ' , y los espacios se conservan. La cadena vacía se puede especificar utilizando una cadena entre comillas.
  • O cadena sin comillas, que consiste en una secuencia de caracteres que no son de espacio en blanco, y no contiene \ o ' .
  • El espacio entre 2 cadenas sin comillas los delimitará. El espacio no es necesario para delimitar otros casos.

En aras de la simplicidad, supongamos que la entrada no contiene una nueva línea (en el caso real, debe considerarla). Se agregará a la complejidad de la expresión regular sin demostrar el punto.

La expresión regular SIN PROCESAR para la secuencia de una sola cita es '(?:[^\\']|\\[\\'])*+'
Y la expresión regular RAW para cadena sin comillas es [^\s'\\]++
Sin embargo, no es necesario que te preocupes demasiado por las 2 piezas de expresiones regulares anteriores.

La solución a continuación con \G puede asegurar que cuando el motor no encuentra ninguna coincidencia, todos los caracteres desde el comienzo de la cadena hasta la posición del último partido hayan sido consumidos. Como no puede omitir el carácter, el motor dejará de coincidir cuando no encuentre una coincidencia válida para ambas especificaciones de tokens, en lugar de tomar elementos aleatorios en el rest de la cadena.

Construcción

En el primer paso de la construcción, podemos armar esta expresión regular:

 \G(?:'((?:[^\\']|\\[\\'])*+)'|([^\s'\\]++)) 

O simplemente ponga (esto no es regex, solo para que sea más fácil de leer):

 \G(Singly_quote_regex|Unquoted_regex) 

Esto coincidirá con el primer token solamente, ya que cuando intenta coincidir por segunda vez, la coincidencia se detiene en el espacio antes de 'some input...


Solo tenemos que agregar un bit para permitir 0 o más espacio, de modo que en la coincidencia posterior, el espacio en la posición que dejó la última coincidencia se consum:

 \G *+(?:'((?:[^\\']|\\[\\'])*+)'|([^\s'\\]++)) 

La expresión regular anterior ahora identificará correctamente los tokens, como se ve aquí .


La expresión regular se puede modificar aún más para que devuelva el rest de la cadena cuando el motor no puede recuperar ningún token válido:

 \G *+(?:'((?:[^\\']|\\[\\'])*+)'|([^\s'\\]++)|((?s).+$)) 

Dado que la alternancia se prueba en orden de izquierda a derecha, la última alternativa ((?s).+$) Coincidirá si y solo si la cadena siguiente no constituye un token válido entre comillas o sin cita. Esto se puede usar para verificar el error.

El primer grupo de captura contendrá el texto dentro de la secuencia de una sola cita, que necesita un procesamiento adicional para convertirse en el texto deseado (no es realmente relevante aquí, así que lo dejo como ejercicio para los lectores). El segundo grupo de captura contendrá la cadena sin comillas. Y el tercer grupo de captura actúa como un indicador de que la cadena de entrada no es válida.

Demostración para la expresión regular final

Conclusión

El ejemplo anterior es una demostración de un escenario de uso de \G en tokenización. Puede haber otros usos que no he encontrado.