Подшаблон в регулярном выражении не может быть разыменован?
У меня есть следующий скрипт 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
или строка регулярного выражения.