Perl: лучший способ сопоставить, сохранить и заменить регулярное выражение во всем мире - PullRequest
5 голосов
/ 13 августа 2011

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

Пример:

my $re = qr{\wat};
my $text = "a cat a hat the bat some fat for a rat";
... (substitute $re -> 'xxx' saving matches in @matches)
# $text -> 'a xxx a xxx the xxx some xxx for a xxx'
# @matches -> qw(cat hat bat fat rat)

Я пробовал: @matches = ($text =~ s{($re)}{xxx}g) но это дает мне счет.

Должен ли я добавить исполняемый код в конец шаблона $re?

Обновление: вот метод, который использует расширенный шаблон выполнения кода (?{ ... }):

use re 'eval';  # perl complained otherwise
my $re = qr{\wat};
my $text = "a cat a hat the bat some fat for a rat";

my @x;
$text =~ s{ ($re)(?{ push(@x, $1)}) }{xxx}gx;

say "text = $text";
say Dumper(\@x); use Data::Dumper;

Ответы [ 3 ]

3 голосов
/ 13 августа 2011

Если под «гладким» вы подразумеваете «использует необычно используемые языковые функции» или «заставит других программистов ломать голову», то, возможно, это решение для вас:

my ($temp, @matches);

push @matches, \substr($text, $-[0], $+[0] - $-[0]) while $text =~ /\wat/g;

$temp = $$_, $$_ = 'xxx', $_ = $temp for reverse @matches;
3 голосов
/ 13 августа 2011

Это похоже на подход в вашем обновлении, но немного проще для чтения:

$text =~ s/($re)/push @x, $1; 'xxx'/ge;

Или так (вероятно, медленнее):

push @x, $1 while $text =~ s/($re)/xxx/;

Но, действительночто-то не так с unslick ?

my @x = $text =~ /($re)/g;
$text =~ s/($re)/xxx/g;
1 голос
/ 13 августа 2011
my @x = map { $str =~ s/$_/xxx/; $_ } $str =~ /($re)/g;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...