如何在 Perl 中进行条件("if exist" 逻辑)搜索和替换?
How to do conditional ("if exist" logic) search & replace in Perl?
在我的 Perl 脚本中,我想使用正则表达式进行条件搜索和替换:查找特定模式,如果该模式存在于散列中,则将其替换为其他内容。
比如我要搜索"pattern1"和"pattern2"的组合,如果hash中存在后者,则将组合替换为"pattern1"和"replacement"。我尝试了以下方法,但它根本没有做任何事情。
$_ =~ s/(pattern1)(pattern2)/replacement/gs if exists $my_hash{};
我也试过类似的东西:
$_ =~ s/(pattern1)(pattern2) && exists $my_hash{}/replacement/gs;
也什么都不做,就好像没有找到匹配项。
谁能帮我解决这个正则表达式问题?谢谢~
有什么问题(如不工作)
if (exists($h{$patt1)) { $text =~ s/$patt1$patt2/$patt1replacement/g; }
如果 $patt1
作为哈希中的键存在,那么您可以继续将 $patt1$patt2
替换为 $patt1$replacement
。当然,如果在$text
中找到$patt1$patt2
,否则什么也不会发生。您的第一个代码片段是循环的,而第二个代码片段根本不能那样工作。
如果你首先想要 $patt1$patt2
, 和 散列键,那么你似乎必须慢慢来
if ($str =~ /$patt11$patt2/ && exists $h{$patt2}) {
$str =~ s/$patt1$patt2/$patt1$replacement/gs;
}
如果这就是您想要的,那么它真的很简单:您需要两个不相关的条件,无论您如何扭转它。不能合并它们,因为它会是循环的。
从结果的角度来看,它们是一样的。如果任一条件失败,则不会发生任何事情,无论您检查它们的顺序如何。
注意 或者也许你不必慢慢来,请参阅 Sobrique 的 post。
我会用不同的方式来做。看起来你有一个 'search this, replace that' 散列。
所以:
#!/usr/bin/env perl
use strict;
use warnings;
#our 'mappings'.
#note - there can be gotchas here with substrings
#so make sure you anchor patterns or sort, so
#you get the right 'substring' match occuring.
my %replace = (
"this phrase" => "that thing",
"cabbage" => "carrot"
);
#stick the keys together into an alternation regex.
#quotemeta means regex special characters will be escaped.
#you can remove that, if you want to use regex in your replace keys.
my $search = join( "|", map {quotemeta} keys %replace );
#compile it - note \b is a zero width 'word break'
#so it will only match whole words, not substrings.
$search = qr/\b($search)\b/;
#iterate the special DATA filehandle - for illustration and a runnable example.
#you probably want <> instead for 'real world' use.
while (<DATA>) {
#apply regex match and replace
s/(XX) ($search)/ $replace{}/g;
#print current line.
print;
}
##inlined data filehandle for testing.
__DATA__
XX this phrase cabbage
XX cabbage carrot cabbage this phrase XX this phrase
XX no words here
and this shouldn't cabbage match this phrase at all
通过这样做,我们将您的哈希键转换为正则表达式(您可以打印它 - 看起来像:(?^:\b(cabbage|this\ phrase)\b)
插入替换模式。如果密钥存在,这将 仅 匹配,因此您可以安全地进行替换操作。
注意 - 我添加了 quotemeta
,因为它会转义键中的任何特殊字符。 \b
是一个 "word boundary" 匹配项,因此它不会在单词中执行子字符串。 (很明显,如果你确实想要那个,那就摆脱它们)
以上给出了输出:
XX that thing cabbage
XX carrot carrot cabbage this phrase XX that thing
XX no words here
and this shouldn't cabbage match this phrase at all
如果您想省略没有 模式匹配的行,您可以在正则表达式之后添加&& print;
。
在我的 Perl 脚本中,我想使用正则表达式进行条件搜索和替换:查找特定模式,如果该模式存在于散列中,则将其替换为其他内容。
比如我要搜索"pattern1"和"pattern2"的组合,如果hash中存在后者,则将组合替换为"pattern1"和"replacement"。我尝试了以下方法,但它根本没有做任何事情。
$_ =~ s/(pattern1)(pattern2)/replacement/gs if exists $my_hash{};
我也试过类似的东西:
$_ =~ s/(pattern1)(pattern2) && exists $my_hash{}/replacement/gs;
也什么都不做,就好像没有找到匹配项。
谁能帮我解决这个正则表达式问题?谢谢~
if (exists($h{$patt1)) { $text =~ s/$patt1$patt2/$patt1replacement/g; }
如果 $patt1
作为哈希中的键存在,那么您可以继续将 $patt1$patt2
替换为 $patt1$replacement
。当然,如果在$text
中找到$patt1$patt2
,否则什么也不会发生。您的第一个代码片段是循环的,而第二个代码片段根本不能那样工作。
如果你首先想要 $patt1$patt2
, 和 散列键,那么你似乎必须慢慢来
if ($str =~ /$patt11$patt2/ && exists $h{$patt2}) {
$str =~ s/$patt1$patt2/$patt1$replacement/gs;
}
如果这就是您想要的,那么它真的很简单:您需要两个不相关的条件,无论您如何扭转它。不能合并它们,因为它会是循环的。
从结果的角度来看,它们是一样的。如果任一条件失败,则不会发生任何事情,无论您检查它们的顺序如何。
注意 或者也许你不必慢慢来,请参阅 Sobrique 的 post。
我会用不同的方式来做。看起来你有一个 'search this, replace that' 散列。
所以:
#!/usr/bin/env perl
use strict;
use warnings;
#our 'mappings'.
#note - there can be gotchas here with substrings
#so make sure you anchor patterns or sort, so
#you get the right 'substring' match occuring.
my %replace = (
"this phrase" => "that thing",
"cabbage" => "carrot"
);
#stick the keys together into an alternation regex.
#quotemeta means regex special characters will be escaped.
#you can remove that, if you want to use regex in your replace keys.
my $search = join( "|", map {quotemeta} keys %replace );
#compile it - note \b is a zero width 'word break'
#so it will only match whole words, not substrings.
$search = qr/\b($search)\b/;
#iterate the special DATA filehandle - for illustration and a runnable example.
#you probably want <> instead for 'real world' use.
while (<DATA>) {
#apply regex match and replace
s/(XX) ($search)/ $replace{}/g;
#print current line.
print;
}
##inlined data filehandle for testing.
__DATA__
XX this phrase cabbage
XX cabbage carrot cabbage this phrase XX this phrase
XX no words here
and this shouldn't cabbage match this phrase at all
通过这样做,我们将您的哈希键转换为正则表达式(您可以打印它 - 看起来像:(?^:\b(cabbage|this\ phrase)\b)
插入替换模式。如果密钥存在,这将 仅 匹配,因此您可以安全地进行替换操作。
注意 - 我添加了 quotemeta
,因为它会转义键中的任何特殊字符。 \b
是一个 "word boundary" 匹配项,因此它不会在单词中执行子字符串。 (很明显,如果你确实想要那个,那就摆脱它们)
以上给出了输出:
XX that thing cabbage
XX carrot carrot cabbage this phrase XX that thing
XX no words here
and this shouldn't cabbage match this phrase at all
如果您想省略没有 模式匹配的行,您可以在正则表达式之后添加&& print;
。