2014-04-19 5 views
0

J'essaye de comparer chaque mot dans une liste à une chaîne pour trouver des mots assortis, mais je ne peux pas sembler obtenir ceci pour fonctionner.Perl regex ne correspond pas comme prévu

Voici quelques exemples de code

my $sent = "this is a test line"; 


foreach (@keywords) {  # array of words (contains the word 'test') 
    if ($sent =~ /$_/) { 
    print "match found"; 
    } 
} 

Il semble fonctionner si j'entrer manuellement /test/ au lieu de $_, mais je ne peux pas entrer des mots manuellement.

+0

Quand je mets '@ keywords = ('test'); 'avant cela et l'exécuter, j'obtiens' match trouvé'. –

+0

Montrez comment vous définissez '@ keywords'. – Barmar

Répondre

0

Votre code fonctionne correctement. J'espère que vous avez use strict et use warnings en place dans le vrai programme? Voici un exemple où j'ai peuplé @keywords avec quelques éléments, y compris test.

use strict; 
use warnings; 

my $sent = "this is a test line"; 
my @keywords = qw/ a b test d e /; 

foreach (@keywords) { 
    if ($sent =~ /$_/) { 
    print "match found\n"; 
    } 
} 

sortie

match found 
match found 
match found 

donc votre tableau ne contient pas ce que vous pensez. Je serais prêt à parier que vous avez lu les données d'un fichier ou du clavier et oublié de supprimer le retour à la fin de chaque mot avec chomp.

Vous pouvez le faire en écrivant

chomp @keywords 

qui va supprimer un saut de ligne (si elle existe) de la fin de tous les éléments de @keywords. Pour voir le contenu réel de @keywords, vous pouvez ajouter ces lignes à votre programme

use Data::Dumper; 
$Data::Dumper::Useqq = 1; 
print Dumper \@keywords; 

Vous verrez également que les éléments a et e produisent un match ainsi que test, que je suppose que vous ne voulez pas. Vous pouvez ajouter une limite de mot métacaractère \b avant et après la valeur de $_, comme celui-ci

foreach (@keywords) { 
    if ($sent =~ /\b$_\b/) { 
    print "match found\n"; 
    } 
} 

mais la définition de l'expression régulière d'un mot est très restrictive et permet que des caractères alphanumériques ou un trait de soulignement _, si Roger's , "essay", 99%, et nicely-formatted ne sont pas des "mots" dans ce sens. En fonction de vos données réelles, vous pouvez vouloir quelque chose de différent.

Enfin, je voudrais écrire cette boucle plus en utilisant de manière compacte for au lieu de foreach (ils sont identiques à tous égards) et le formulaire de modification de l'instruction postfixé de if, comme celui-ci

for (@keywords) { 
    print "match found\n" if $sent =~ /\b$_\b/; 
} 
+0

Je suppose que vous avez raison concernant les nouvelles lignes. – Barmar

+0

@Barmar: Oui, je pense que je suis trop :) – Borodin