J'ai cet exemple de code
dear.{0,6}(brother|friend)
$ 1 affichera la correspondance qui est "Cher frère". Existe-t-il un moyen d'obtenir la regepx complète qui correspond à cette chaîne?
Dans ce cas
#!/usr/bin/perl use strict; use warnings; my $string = "Dear Brother,fgfgfg Test Test2 Soon trthggh"; if ($string =~ /(expr1|expr2|dear.{0,6}(brother|friend)|Soon)/i){print "$1";}
C'est possible de le faire?
3 Réponses :
J'ai cette solution fonctionnelle. Mais sur trop d'expressions, je pense que la boucle peut ralentir le script. D'autres idées plus intéressantes sont les bienvenues, mais arrêtez de me parler de $ 1 ou $ &.
#!/usr/bin/perl use strict; use warnings; my $string = "Dear Brother, fgfgfg Test Test2 Soon trthggh"; my $regexstring = "expr1|expr2|dear.{0,6}(brother|friend)|Soon|out.php\?s=(7644|4206|6571|4205)"; my @regexarray = ("expr1", "expr2", "dear.{0,6}(brother|friend)", "Soon", "out.php\?s=(7644|4206|6571|4205)"); if ($string =~ /($regexstring)/i){ my $match = $1; for my $expr (@regexarray){ print "$expr\n" if ($match =~ /($expr)/i); } }
Pourquoi ne pas créer la regexstring à partir du regexarray et ajouter des captures nommées dans la même exécution? my $ i = 0; my $ regexstring = join "|", map {qr / (? <$ i ++> $ _) /} @regexarray; if ($ string = ~ / $ regexstring /) {print @regexstring [clés% +]}
Si vous créez de toute façon l'expression régulière en utilisant un programme, il est facile d'injecter les séquences (? <...>)
appropriées et de regarder ensuite laquelle (s) correspond (s) par la suite. Adapter le programme que vous avez posté en tant que première tentative:
Found <Dear Brother> Matched via group_2 => Dear Brother Matched via /(?^i:dear.{0,6}(brother|friend))/
J'ai changé les chaînes en expressions régulières ci-dessus pour faciliter les guillemets et l'insensibilité à la casse.
#!/usr/bin/perl use strict; use warnings; my $string = "Dear Brother, fgfgfg Test Test2 Soon trthggh"; my @regexarray = (qr/expr1/, qr/expr2/, qr/dear.{0,6}(brother|friend)/i, qr/Soon/, qr/out.php\?s=(7644|4206|6571|4205)/); my $i= 0; my $regexstring = join "|", map { my $groupname= sprintf 'group_%d', $i++; qr/(?<$groupname>$_)/i } @regexarray; if ($string =~ /($regexstring)/i){ my $match = $1; print "Found <$1>\n"; print "Matched via "; (my $found) = keys %+; print "$found => $+{$found}\n" for keys %+; $found =~ /(\d+)$/ or die "Invalid group name '$found'"; my $index = $1; print "Matched via /$regexarray[ $index ]/\n"; }
Vous pourriez peut-être utiliser cette approche:
my $part2 = "(brother|friend)"; my $part1 = "(expr1|expr2|dear.{0,6}$part2|Soon)"; my $string = "Dear Brother,fgfgfg Test Test2 Soon trthggh"; if ($string =~ /$part1/i){print "$part1";}
Je ne connais plus de méthode automatisée. Peut-être que vous devez pirater un moteur d'expression régulière, sans utiliser directement Perl.
Je ne veux pas de 1 $! J'ai besoin d'un moyen d'obtenir l'expression complète qui correspond à la chaîne.
Peut-être
if (/ (expr1) /) {vous savez que c'est expr1} ... elsif (/ (cher ...) /) {c'est ce re}
, ce qui signifie remplacer le| < / code> s avec un groupe de
if
sCette approche conditionnelle pour chaque regex n'est pas possible. J'ai des centaines d'expressions régulières pour les comparer.
Je l'ai trouvé ... Backreference nommé. Corion, pouvez-vous donner quelques exemples car perldoc est très pauvre.
Si ma réponse a fonctionné pour vous, pouvez-vous l'accepter? stackoverflow.com/help/someone-answers