Как получить доступ к захваченным подстрокам после успешного сопоставления регулярных выражений в Perl? - PullRequest
1 голос
/ 23 июня 2009

Я ищу строку в Perl и сохраняю ее в другой скалярной переменной. Я хочу напечатать эту скалярную переменную. Код ниже, похоже, не работает. Я не уверен, что идет не так и как это сделать. Почему он печатает '1', когда его нет в программе?

Данные, на которых он работает

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

Вот мой код:

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

OUTPUT

reached here1

1 

reached here 3 

reached here1 

1 

reached here 3 

Ответы [ 4 ]

7 голосов
/ 23 июня 2009

Операция сопоставления с регулярным выражением возвращает true (1) для успешного совпадения, в противном случае - false. Если вы хотите получить совпадение, попробуйте выполнить одно из следующих действий:

  • использовать переменные соответствия $ 1, $ 2 ...
  • совпадение в контексте списка ($m1, $m2) = $string =~ /$regex/

Обратите внимание, что вам нужно использовать захваты в вашем регулярном выражении, чтобы они работали. Что вы еще не делаете.

Вы должны взглянуть на полную документацию в perlop , раздел "Операторы, похожие на регулярные выражения"

3 голосов
/ 23 июня 2009

JB правильно. Ваше регулярное выражение должно будет использовать захваты (которые определены в скобках) для отдельных частей, которые будут собраны. Если вы хотите захватить все элементы в вашей строке, вам нужно это:

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 голос
/ 23 июня 2009

m// возвращает захваченные совпадения в контексте списка:

#!/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
0 голосов
/ 23 июня 2009

Я не могу воспроизвести ваши результаты. Что я получаю:

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

Несмотря на это, он печатает 1, потому что вы сказали ему: оператор print для этого находится внутри цикла while, и то, что он печатает, указывает на то, соответствует ли шаблон.

Вы бы выиграли от правильного отступа кода:

#!/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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...