【问题标题】:substitute multiple substrings with per substring substitution用每个子字符串替换来替换多个子字符串
【发布时间】:2017-12-06 20:13:39
【问题描述】:

关于以下字符串:“狗吃猫,还是你的猫吃老鼠?”

我想在 Perl 中使用 s/// 将每次出现的“dog”替换为“cat”,将“cat”替换为“mouse”,将“mouse”替换为“dog” ”。

所以结果是:“猫吃老鼠,还是你的老鼠吃狗?”

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

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

ps:当然我想使用正确的复数形式,例如“mice”而不是“mouses”

【问题讨论】:

  • 创建一个时间值,用于将 EG cat 更改为 ## 并在关闭圆圈后将 ## 更改为 mouse...
  • 您可以简单地将您的真实输入字符串拆分为标记/单词吗?例如split(/\b/,$_) 上面的例子。 [我假设真正的问题是“略有不同”]
  • @Andrzej A. Filip:非常感谢您的回复,我会一直使用拆分方法,但我很快就会了解如何使用哈希。

标签: regex string perl substitution


【解决方案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;

从哈希键和测试构造正则表达式的详细版本:

#!/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?

【讨论】:

  • 这里的替换运算符不需要/e
  • 首先,非常感谢!但我有点惊讶,这个简单的问题需要如此广泛的解决方案。
  • @ic23oluk 生骨“概念证明”版本:%S=(dog=&gt;'cat',cat=&gt;'mouse'); s/\b(dog|cat)\b/$S{$1}/g。答案中的版本更难编码,但更容易维护——我个人更喜欢这种低成本的方法。
猜你喜欢
  • 2016-09-10
  • 2019-11-20
  • 2011-09-01
  • 2021-06-13
  • 2011-04-06
  • 1970-01-01
  • 2011-12-01
  • 2011-06-06
相关资源
最近更新 更多