2009-06-23 5 views
1

Je cherche une chaîne dans Perl et la stocke dans une autre variable scalaire. Je veux imprimer cette variable scalaire. Le code ci-dessous ne semble pas fonctionner. Je ne suis pas sûr de ce qui ne va pas et de la bonne façon de procéder. Pourquoi imprime-t-il '1' quand il n'existe pas dans le programme?Comment accéder aux sous-chaînes capturées après une correspondance regex réussie en Perl?

données, il est en cours d'exécution sur

DONNÉES

 13 E 0.496 -> Q 0.724 
     18 S 0.507 -> R 0.513 
     19 N 0.485 -> S 0.681 
     21 N 0.557 -> K 0.482 

Voici mon code:

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

my $find = '\s{10}[0-9]{2}\s[A-Z]'; #regex. it can also be '\s{10}[0-9]{2}\s[A-Z]' 
            #both dont seem to work 
my @element; 
open (FILE, "/user/run/test") || die "can't open file \n"; 
while (my $line = <FILE>) { 
    chomp ($line); 
    print "reached here1 \n"; # to test whether it reading the program properly 
    my $value = $line=~ /$find/ ; 
    print "reached here 3 \n"; # to test whether it reading the program properly 
    print "$value \n"; 
} 
exit; 

SORTIE

reached here1 

1 

reached here 3 

reached here1 

1 

reached here 3 
+1

double possible de http://stackoverflow.com/questions/1029896/comment lire l'information-du-fichier-en-utilisant-regex-et-imprime-le/1029928 # 1029928 –

Répondre

7

L'opération de correspondance d'expressions régulières renvoie true (1) pour le succès de la correspondance, false dans le cas contraire. Si vous souhaitez récupérer le match, vous devriez essayer l'un des suivants:

  • utiliser les variables match 1 $, 2 $ ...
  • correspondance dans le contexte de la liste ($m1, $m2) = $string =~ /$regex/

Notez que vous avez besoin utiliser des captures dans votre regex pour que cela fonctionne. Ce que tu ne fais pas encore.

Vous devriez jeter un oeil à la documentation complète perlop, section « Regexp apostrophe » Les opérateurs

0

Je suis incapable de reproduire vos résultats. Ce que je reçois est:

reached here1 
reached here 3 
1 
reached here1 
reached here 3 
1 
reached here1 
reached here 3 
1 
reached here1 
reached here 3 
1 

Peu importe, il est l'impression 1 parce que vous avez dit à: la déclaration d'impression de le faire est à l'intérieur de la boucle while, et ce qu'il est l'impression est une indication du motif ou non apparié.

Vous souhaitez bénéficier de indenter votre code correctement:

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

my $find = '\s{10}[0-9]{2}\s[A-Z]'; #regex. it can also be '\s{10}[0-9]{2}\s[A-Z]' 
            #both dont seem to work 
my @element; 
open (FILE, "foo") || die "can't open file \n"; 
while (my $line = <FILE>) { 
    chomp ($line); 
    print "reached here1 \n"; # to test whether it reading the program properly 
    my $value = $line=~ /$find/ ; 
    print "reached here 3 \n"; # to test whether it reading the program properly 
    print "$value \n"; 
} 
exit; 
3

JB est correcte. Votre expression régulière doit utiliser des captures (définies par des parenthèses) pour les parties individuelles à collecter. Si vous voulez capturer tous les éléments de votre ligne, vous voulez ceci:

my $find = '\s{10}([0-9]{2})\s([A-Z])'; 
my $field1; 
my $field2; 
while (my $line = <FILE>) { 
    chomp ($line); 
    if ($line=~ /$find/) { 
     $field1 = $1; 
     $field2 = $2; 
     # Do something with current line's field 1 and field 2 
    } 
} 
1

m// renvoie les résultats dans le contexte de saisies liste:

#!/usr/bin/perl 

use strict; 
use warnings; 

my $pattern = qr/^\s{10}([0-9]{2})\s[A-Z]/; 

while (my $line = <DATA>) { 
    if (my ($n) = $line =~ $pattern) { 
     print "$n\n"; 
    } 
} 

__DATA__ 
      13 E 0.496 -> Q 0.724 
      18 S 0.507 -> R 0.513 
      19 N 0.485 -> S 0.681 
      21 N 0.557 -> K 0.482 
Questions connexes