Perl可以一次性用自己的替代词替换多个关键词吗?

Kev*_*eve 8 regex perl

考虑一个包含以下内容的文本文件:

apple apple pear plum apple cherry pear apple  
cherry plum plum pear apple cherry pear pear apple plum
Run Code Online (Sandbox Code Playgroud)

并考虑perl one-liner:

perl -pe "s/apple/green/g and s/pear/yellow/g and s/plum/blue/g and s/cherry/red/g" < fruits.txt
Run Code Online (Sandbox Code Playgroud)

这取代了每种水果的颜色.
现在,这可以用一个s /// g以某种方式完成,而不是上面的四个吗?

我也关注水果词的顺序.
如果我的样本不包含"apple",则其他替换都不会完成.我该怎么解决这个问题?

请注意:我希望将解决方案保持为单行.
因此,定义哈希,读取文件以及需要多行perl代码的其他解决方案并不能让我前进.

这更像是一种好奇心,而不是一个项目所依赖的生死攸关的问题.现在困扰我好几天了,并且认为一个更有经验的perl用户可以帮助解决心跳,或者让我摆脱困境,直接告诉我这不可能按照我想要的方式完成.

ike*_*ami 12

更换

perl -pe's/apple/green/g and s/pear/yellow/g and ...' fruits.txt
Run Code Online (Sandbox Code Playgroud)

perl -pe's/apple/green/g; s/pear/yellow/g; ...' fruits.txt
Run Code Online (Sandbox Code Playgroud)

a => bb => c更快,没有问题:

perl -pe'
   BEGIN {
      %subs=qw(apple green pear yellow plum blue cherry red);
      $re=join "|", map quotemeta, keys %subs;
      $re = qr/($re)/;
   }
   s/$re/$subs{$1}/g;
' fruits.txt
Run Code Online (Sandbox Code Playgroud)

其他潜在问题:

  • 如果你想要更换apple但不是apples什么?
  • 如果哈希有钥匙beebeer

使用合适的锚固(例如$re = qr/\b($re)\b/)可以解决这两个问题.第二个也可以通过减少长度(sort { length($b) <=> length($a) } keys %subs)来对键进行排序来解决.

(为了便于阅读,您可以删除我添加的换行符.)


mkb*_*mkb 5

perl -pe '%a=qw(apple green pear yellow plum blue cherry red);$b=join("|",keys %a);s/($b)/$a{$1}/g' < fruits.txt

  • 也许这应该是"加入"\ b |\b"`以避免像'菠萝`变成'pinegreen`这样的东西.另外,考虑按长度顺序对密钥进行排序以进一步减少这种情况. (4认同)

ruz*_*ruz 5

perl -E 'my %h = qw(apple green foo bar); say "apple foo" =~ s/(apple|foo)/$h{$1}/rge;'
Run Code Online (Sandbox Code Playgroud)