如何在 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;