Подшаблон в регулярном выражении не может быть разыменован?

У меня есть следующий скрипт Perl для извлечения чисел из журнала. Похоже, что группа без захвата с ?: не работает, когда я определяю подшаблон в переменной. Это работает, только когда я опускаю группировку в шаблоне регулярных выражений или в суб-шаблоне в $number,

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

my $number = '(:?-?(?:(?:\d+\.?\d*)|(?:\.\d+))(?:[Ee][+-]?\d+)?)';
#my $number = '-?(?:(?:\d+\.?\d*)|(?:\.\d+))(?:[Ee][+-]?\d+)?';

open(FILE,"file.dat") or die "Exiting with: $!\n";
while (my $line = <FILE>) {
        if ($line =~ m{x = ($number). y = ($number)}){
        print "\$1= $1\n";
        print "\$2= $2\n";
        print "\$3= $3\n";
        print "\$4= $4\n";
    };
}
close(FILE);

Выход для этого кода выглядит следующим образом:

$1= 12.15
$2= 12.15
$3= 3e-5
$4= 3e-5

для ввода:

asdf x = 12.15. y = 3e-5 yadda

Эти удвоенные выходы не желательны.

Это из-за m{} стиль в отличие от обычного m// шаблоны для регулярных выражений? Я знаю только первый стиль получения переменных (подстрок) в моих выражениях регулярных выражений. Я только что заметил это для обратных ссылок, так что, возможно, есть другие различия для метасимволов?

2 ответа

Решение

Разделители, которые вы используете для регулярного выражения, не вызывают никаких проблем, но следующее:

(:?-?(?:(?:\d+\.?\d*)|(?:\.\d+))(?:[Ee][+-]?\d+)?)
 ^^
Notice this isn't a capturing group, it is an optional colon :

Вероятно, ошибка опечатки, но это вызывает проблемы.

Изменить: похоже, что это не опечатка, я заменил переменные в регулярном выражении, и я получил это:

x = ((:?-?(?:(?:\d+\.?\d*)|(?:\.\d+))(?:[Ee][+-]?\d+)?)). y = ((:?-?(?:(?:\d+\.?\d*)|(?:\.\d+))(?:[Ee][+-]?\d+)?))
    ^^           first and second group               ^^      ^^    third and fourth grouop                     ^^

Как вы можете видеть, первая и вторая группы захвата захватывают одно и то же, то же самое происходит с третьей и четвертой группой захвата.

Ты собираешься пнуть себя...

Ваше регулярное выражение читается как:

capture {
 maybe-colon
 maybe-minus
 cluster {     (?:(?:\d+\.?\d*)|(?:\.\d+))
  cluster {    (?:\d+\.?\d*)
   1+ digits
   maybe-dot
   0+ digits
  }
  -or-
  cluster {    (?:\.\d+)
   dot
   1+digits
  }
 }
 maybe cluster {
   E or e
   maybe + or -
   1+ digets
 }             (?:[Ee][+-]?\d+)?
}

... это то, что вы ищете.

Однако, когда вы затем выполняете свое фактическое регулярное выражение, вы делаете:

$line =~ m{x = $number. y = $number})

(фигурные скобки отвлекают внимание... вы можете использовать любой \W, если m или же s был указан)

То, что это спрашивает, это capture независимо от регулярного выражения, определенного в $number это.... что само по себе, capture.... отсюда $1 а также $2 быть тем же самым

Просто удалите скобки захвата из любого $number или строка регулярного выражения.

Другие вопросы по тегам