2 votes

Perl : afficher l'expression régulière, pas la correspondance

J'ai ce code d'exemple

#!/usr/bin/perl
use strict;
use warnings;
my $string = "Cher Frère,fgfgfg Test Test2 Bientôt trthggh";

if ($string =~ /(expr1|expr2|cher.{0,6}(frère|ami)|Bientôt)/i){print "$1";}

$1 affichera la correspondance qui est "Cher Frère". Y a-t-il un moyen d'obtenir l'expression régulière complète qui correspond à cette chaîne?

Dans ce cas

cher.{0,6}(frère|ami)

Est-il possible de le faire?

5voto

Corion Points 3649

Si vous créez l'expression régulière en utilisant un programme de toute façon, il est facile d'injecter les séquences appropriées (?<...>) puis de vérifier ensuite lesquelles ont été trouvées. En adaptant le programme que vous avez posté comme premier essai :

#!/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";
}

J'ai changé les chaînes en expressions régulières ci-dessus pour faciliter les citations et l'insensibilité à la casse.

Sortie

Found 
Matched via group_2 => Dear Brother
Matched via /(?^i:dear.{0,6}(brother|friend))/

2voto

Claude Points 171

Je dispose de cette solution fonctionnelle. Mais sur trop d'expressions, je pense que la boucle peut ralentir le script. D'autres idées meilleures sont les bienvenues, mais s'il vous plaît arrêtez de me parler de $1 ou $&.

#!/usr/bin/perl
use strict;
use warnings;

my $string = "Cher Frère, fgfgfg Test Test2 Bientôt trthggh";
my $regexstring = "expr1|expr2|cher.{0,6}(frère|ami)|Bientôt|out.php\?s=(7644|4206|6571|4205)";
my @regexarray = ("expr1", "expr2", "cher.{0,6}(frère|ami)", "Bientôt", "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);
    }
}

-1voto

jiandingzhe Points 189

Peut-être pourriez-vous utiliser cette approche :

my $part2 = "(frère|ami)";
my $part1 = "(expr1|expr2|cher.{0,6}$part2|Bientôt)";

my $string = "Cher Frère,fgfgfg Test Test2 Bientôt trthggh";
if ($string =~ /$part1/i){print "$part1";}

Je ne connais pas de moyen automatisé supplémentaire. Peut-être devrez-vous pirater un moteur regex, sans utiliser directement Perl.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X