用每个子串替换替换多个子串

时间:2017-07-03 14:04:26

标签: regex string perl substitution

关于以下字符串:"狗是否吃猫,或者你的猫是否吃了老鼠?"

我想在Perl中使用 s /// 来替换每次出现的" dog"用" cat"," cat"与"鼠标"和"鼠标"用"狗"。

结果是:"猫吃老鼠,或者老鼠吃狗了吗?"

我的问题是,用猫代替狗后,猫会出现两次,但我只想替换原来的猫。

我知道我可以简单地写几个非全局的替换,但我想知道是否有一个单行代码。

ps:当然我想使用正确的复数,例如“老鼠”而不是“老鼠”

1 个答案:

答案 0 :(得分:1)

您可以使用正则表达式查找所有匹配项和哈希值以查找替换项 下面是从散列保持匹配=>替换映射的键中找到构造正则表达式的脚本。

裸骨“概念证明”版本:

%S=(dog=>'cat',cat=>'mouse'); # hash with match=>replacements mappings
# substitute "dog" and "cat" for values provided by S hash
s/\b(dog|cat)\b/$S{$1}/g;
# OR if if can easily split input string into "words"
#    substitute "words" present in S hash and keep the rest unchanged
s{\b(\S+?)\b}{$S{$1}//$1}g;

精心制作版本,从散列键和测试构建regexp:

#!/usr/bin/perl
use strict;
use warnings;

# %S - hash keeping match=>replacements pairs
my %S = (
  dog  => "cat",
  dogs => "cats",
  cat  => "mouse",
  cats => "mice",
  mouse => "dog",
  mice  => "dogs",
);
my $regex = sprintf '\b(?:%s)\b', join('|',sort keys %S);
$regex = qr($regex);
print "REGEX: ",$regex,"\n"; # print regexp for finding all matches

while( <DATA> ) {
  print "IN:  ",$_; # print string before rewriting
  s/($regex)/$S{$1}/g; # Replace all matches by replacements provided by %S hash
  print "OUT: ",$_; # print string after rewriting
}

# Put your tests strings in lines below __DATA__
__DATA__
Do dogs eat cats, or does your cat eat a mouse?
Does firecat fly?