Les regex récursifs comprennent-ils les captures nommées ? Il y a une note dans les docs pour (?{{ code }})
qu'il s'agit d'un sous-modèle indépendant avec son propre ensemble de captures qui sont éliminées lorsque le sous-modèle est terminé. (?PARNO)
que sa "similarité avec (?{{ code }})
. Est (?PARNO)
en jetant ses propres captures nommées quand il a fini ?
J'écris sur les expressions régulières récursives de Perl pour Maîtriser Perl . perlre a déjà un exemple avec des parens équilibrés (je le montre dans Correspondance des parenthèses équilibrées dans les regex Perl ), alors je me suis dit que j'allais essayer les guillemets équilibrés :
#!/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
";
Cela fonctionne et les deux citations apparaissent dans $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 =>
C'est bien. Je le comprends. Cependant, je ne veux pas connaître les chiffres. Donc, je fais du premier groupe de capture une capture nommée et je regarde dans %-
s'attendant à voir les deux sous-chaînes que j'ai vues précédemment dans $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( \%- );
Je ne vois que le premier :
Matched ['Amelia said "I am a camel"']!
$VAR1 = {
'said' => [
'\'Amelia said "I am a camel"\''
]
};
Je m'attendais à ce que (?1)
répéterait tout ce qui se trouve dans le premier groupe de capture, y compris la capture nommée à said
. Je peux corriger un peu cela en nommant une nouvelle capture :
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( \%- );
Maintenant, j'obtiens ce que j'attendais :
Matched ['Amelia said "I am a camel"']!
$VAR1 = {
'said' => [
'\'Amelia said "I am a camel"\'',
'"I am a camel"'
]
};
J'ai pensé que je pourrais résoudre ce problème en déplaçant la capture nommée vers le haut d'un niveau :
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( \%- );
Mais, cela n'attrape pas la plus petite sous-chaîne dans said
soit :
Matched ['Amelia said "I am a camel"']!
$VAR1 = {
'said' => [
'\'Amelia said "I am a camel"\''
]
};
Je pense avoir compris, mais je sais aussi qu'il y a des gens ici qui touchent au code C qui permet de le faire :)
Et, alors que j'écris ceci, je pense que je devrais surcharger la cravate STORE pour %-
pour le découvrir, mais alors je devrais trouver comment le faire.