在我的Perl脚本中我想做条件搜索&使用正则表达式替换:查找某个模式,如果模式存在于哈希中,则将其替换为其他模式。
例如,我想搜索“pattern1”和“pattern2”的组合,如果后者存在于散列中,则将组合替换为“pattern1”和“replacement”。我尝试了以下内容,但它根本没有做任何事情。
$_ =~ s/(pattern1)(pattern2)/$1replacement/gs if exists $my_hash{$2};
我也试过像这样的东西:
$_ =~ s/(pattern1)(pattern2) && exists $my_hash{$2}/$1replacement/gs;
也什么都不做,好像没有找到匹配。
任何人都可以帮我解决这个正则表达式问题吗? THX〜
答案 0 :(得分:2)
我会以不同的方式做到这一点。看起来你有一个搜索它,取而代之的是'哈希值。
所以:
#!/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)/$1 $replace{$2}/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
是一个&#34;字边界&#34;匹配所以它不会在单词中进行子串。 (显然,如果你做想要那个,那就去除它们)
以上给出了输出:
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;
。
答案 1 :(得分:1)
有什么问题(如不工作)
if (exists($h{$patt1)) { $text =~ s/$patt1$patt2/$patt1$1replacement/g; }
如果$patt1
作为哈希中的键存在,那么您可以继续将$patt1$patt2
替换为$patt1$replacement
。当然,如果在$patt1$patt2
中找到$text
,则不会发生任何事情。您的第一个代码段是循环的,而第二个代码片段根本无法正常工作。
如果您首先需要$patt1$patt2
,和哈希密钥,那么您似乎必须放慢速度
if ($str =~ /$patt11$patt2/ && exists $h{$patt2}) {
$str =~ s/$patt1$patt2/$patt1$replacement/gs;
}
如果这是你想要的,那么它很简单:你需要两个不相关的条件,无论你转向它的方式。无法合并它们,因为它是圆形的。
从结果来看,这些都是一样的。如果任何一种情况失败,无论您检查它们的顺序如何,都不会发生任何事情。
注意或者您可能不会放慢速度,请参阅Sobrique的帖子。