Perl Regex - печать совпадающего значения
Что такое регулярное выражение perl для печати согласованного значения? Например, я хочу напечатать 195
из этой строки
"2011-04-11 00:39:28,736::[main]::INFO (Main.java:73) Test.Main::main() Total Successful Transactions = 195".
Как я могу это сделать? Спасибо заранее
Ответы
Ответ 1
Вы можете использовать круглые скобки в регулярном выражении для захвата подстрок. Захваченные группы хранятся в $1, $2 и т.д. Пример:
while (<>) {
if (/Total Successful Transactions = (\d+)/) {
print "$1\n";
}
}
или, несколько короче:
while (<>) {
print "$1\n" if /Total Successful Transactions = (\d+)/;
}
Ответ 2
Просто хотелось немного перефразировать предыдущие ответы; обратите внимание, что в этом случае:
$ perl -e '$str="the variable Xy = 3 in this case"; print $str =~ /Xy = 3/;'
1
... мы получаем, что 1 печатается - как в "да, я получил матч". Если мы хотим вернуть согласованную текстовую часть, как указано @markusk, "использовать круглые скобки в регулярном выражении для захвата подстрок":
$ perl -e '$str="the variable Xy = 3 in this case"; print $str =~ /(Xy = 3)/;'
Xy = 3
Однако обратите внимание, что у вас может возникнуть проблема с конкатенацией строк с этой идиомой при захвате:
$ perl -e '$str="the variable Xy = 3 in this case"; print $str =~ /Xy = 3/ . "\n";'
1 # OK
$ perl -e '$str="the variable Xy = 3 in this case"; print $str =~ /(Xy = 3)/ . "\n";'
1 # NOT OK
... поэтому, вероятно, лучше держать вещи в этом случае:
$ perl -e '$str="the variable Xy = 3 in this case"; print $str =~ /(Xy = 3)/ ; print "\n";'
Xy = 3 # OK again
Однако, если мы хотим захватить "что-то", скажем цифру, то, поскольку мы используем круглые скобки, мы автоматически возвращаем именно это соответствие этой идиоме (а не всей строке "поиск" ):
$ perl -e '$str="the variable Xy = 3 in this case"; print $str =~ /Xy = (\d)/ ; \
print "\n";'
3
... таким образом, чтобы зафиксировать искомую строку целиком, мы должны ее снова скопировать в круглые скобки:
$ perl -e '$str="the variable Xy = 3 in this case"; print $str =~ /(Xy = (\d))/ ; \
print "\n";'
Xy = 33
.... но мы не получаем того, чего ожидаем, потому что теперь есть два совпадения, $1
и $2
; и, по-видимому, идиома "print $str =~ /.../
" выводит все совпадения (в этом случае "$1$2
" ).
Итак, чтобы получить только искомую строку в этом случае с вложенными совпадениями, теперь мы должны явно указать только $1
:
$ perl -e '$str="the variable Xy = 3 in this case"; $str =~ /(Xy = (\d))/ ; \
print "$1 \n";'
Xy = 3
EDIT oct 2013: Via Присвоить одно из нескольких совпадений регулярных выражений переменной как Perl one-liner (массив разыменования?) - также это может быть сделано для одного лайнера
$ perl -e '$str="the variable Xy = 3 in this case"; \
print ( ( $str =~ /(Xy = (\d))/ )[1] ); print "\n";'
3
... однако обратите внимание на необходимость использования второго огибающего набора круглых скобок для print
для работы с массивом возвращенных (анонимных?) регулярных выражений.
Наконец, в многострочном контексте убедитесь, что сначала "slurp" весь файл/текст в одну строку; затем используйте /s
(однолинейный режим = соответствие новой строки) и /g
(глобальные/множественные совпадения) - и, наконец, убедитесь, что выражение соответствия находится в цикле while
, чтобы перебирать все совпадения:
$ echo "some data
IN
123
OUT
some more data
is about to follow:
IN
256
OUT
done with data
out" | perl -e '$str = do { local $/; <> }; while ($str =~ /(IN(.*?)OUT)/sg) { print "$1\n"} '
IN
123
OUT
IN
256
OUT
Хорошо, надеюсь, это поможет кому-то,
Ура!
Ответ 3
Как насчет просто:
print $string =~ /Total Successful Transactions = (\d+)/;
Вам редко приходится использовать $1
и друзей.
Ответ 4
/(\d+$)/;
print $1;
Я думаю, вы просто хотите номер 195
. Правильно?
Ответ 5
Проверьте цифры в конце перед "
и .
.
#!/usr/bin/env perl
use strict;
use warnings;
my $string = q{"2011-04-11 00:39:28,736::[main]::INFO (Main.java:73) Test.Main::main() Total Successful Transactions = 195".};
my ($number) = $string =~ m{ (\d+) " \. \z}x;
print "Matched number: $number\n" if defined $number;
Ответ 6
my $str = '"2011-04-11 00:39:28,736::[main]::INFO (Main.java:73) Test.Main::main() Total Successful Transactions = 195".';
$str =~ /Total Successful Transactions = (\d+)/;
print $1;
195 будет храниться в $1
Ответ 7
Версия командной строки принятого ответа @markusk довольно компактна:
perl -ne '/Total Successful Transactions = (\d+)/ && print "$1\n";'
Ответ 8
Так же:
if ("2011-04-11 00:39:28,736::[main]::INFO (Main.java:73) Test.Main::main() Total Successful Transactions = 195" =~ /(\d+)$/) {
print $1;
}
После сопоставления сопоставленные группы становятся доступными как $1.. $n.