validator tester regular one regex perl named-captures

regex - tester - ¿`(? PARNO)` de Perl descarta sus propias capturas nombradas cuando termina?



regex javascript validator (1)

Después de jugar con esto, estoy satisfecho de que lo que dije en la pregunta es correcto. Cada llamada a (?PARNO) obtiene un conjunto completo y separado de las variables de coincidencia que descarta al final de su ejecución.

Puede obtener todas las cosas que coinciden en cada patrón secundario utilizando una matriz externa al operador de coincidencia de patrón y empujándola al final del patrón secundario repetido, como en este ejemplo:

#!/usr/bin/perl # nested_carat_n.pl use v5.10; $_ =<<''HERE''; Outside "Top Level ''Middle Level "Bottom Level" Middle'' Outside" HERE my @matches; say "Matched!" if m/ (?(DEFINE) (?<QUOTE_MARK> [''"]) (?<NOT_QUOTE_MARK> [^''"]) ) ( (?<quote>(?&QUOTE_MARK)) (?: (?&NOT_QUOTE_MARK)++ | (?R) )* /g{quote} ) (?{ push @matches, $^N }) /x; say join "/n", @matches;

Lo profundizo en el Capítulo 2 de Mastering Perl , que puedes leer gratis (al menos por un tiempo).

¿Las expresiones regulares recursivas entienden las capturas con nombre? Hay una nota en los documentos para (?{{ code }}) que es un subconjunto independiente con su propio conjunto de capturas que se descartan cuando se hace el subconjunto, y hay una nota en (?PARNO) que es "similar a (?{{ code }}) . ¿ (?PARNO) sus propias capturas nombradas cuando (?PARNO) ?

Estoy escribiendo sobre las expresiones regulares recursivas de Perl para Mastering Perl . perlre ya tiene un ejemplo con parens equilibrados (lo muestro en paréntesis equilibrados a juego en Perl regex ), así que pensé en probar las comillas equilibradas:

#!/usr/bin/perl # quotes-nested.pl use v5.10; $_ =<<''HERE''; He said ''Amelia said "I am a camel"'' HERE say "Matched!" if m/ ( [''"] ( (?: [^''"]+ | ( (?1) ) )* ) [''"] ) /xg; print " 1 => $1 2 => $2 3 => $3 4 => $4 5 => $5 ";

Esto funciona y las dos citas aparecen en $1 y $3 :

Matched! 1 => ''Amelia said "I am a camel"'' 2 => Amelia said "I am a camel" 3 => "I am a camel" 4 => 5 =>

Esta bien. Entiendo que. Sin embargo, no quiero saber los números. Entonces, hago del primer grupo de captura una captura con nombre y lo miro en %- esperando ver las dos subcadenas que vi anteriormente en $1 y $2 :

use v5.10; $_ =<<''HERE''; He said ''Amelia said "I am a camel"'' HERE say "Matched [$+{said}]!" if m/ (?<said> [''"] ( (?: [^''"]+ | (?1) )* ) [''"] ) /xg; use Data::Dumper; print Dumper( /%- );

Solo veo el primero:

Matched [''Amelia said "I am a camel"'']! $VAR1 = { ''said'' => [ ''/'Amelia said "I am a camel"/''' ] };

Esperaba que (?1) repitiera todo en el primer grupo de captura, incluida la captura nombrada a said . Puedo solucionarlo un poco nombrando una nueva captura:

use v5.10; $_ =<<''HERE''; He said ''Amelia said "I am a camel"'' HERE say "Matched [$+{said}]!" if m/ (?<said> [''"] ( (?: [^''"]+ | (?<said> (?1) ) )* ) [''"] ) /xg; use Data::Dumper; print Dumper( /%- );

Ahora obtengo lo que esperaba:

Matched [''Amelia said "I am a camel"'']! $VAR1 = { ''said'' => [ ''/'Amelia said "I am a camel"/''', ''"I am a camel"'' ] };

Pensé que podría solucionar esto moviendo la captura nombrada un nivel superior:

use v5.10; $_ =<<''HERE''; He said ''Amelia said "I am a camel"'' HERE say "Matched [$+{said}]!" if m/ ( (?<said> [''"] ( (?: [^''"]+ | (?1) )* ) [''"] ) ) /xg; use Data::Dumper; print Dumper( /%- );

Pero, esto no capta la subcadena más pequeña en said cualquiera:

Matched [''Amelia said "I am a camel"'']! $VAR1 = { ''said'' => [ ''/'Amelia said "I am a camel"/''' ] };

Creo que entiendo esto, pero también sé que hay personas aquí que realmente tocan el código C que lo hace posible. :)

Y, mientras escribo esto, creo que debería sobrecargar la etiqueta STORE para %- para averiguarlo, pero luego tendría que descubrir cómo hacerlo.