在Perl s /// g中发生了多少次替换?

时间:2010-06-23 16:00:21

标签: regex perl substitution

小例子:

perl -e '$s="aaabbcc";$c=()=$s=~/a/g;print"$c\n$s\n"'(m // g)输出

3
aaabbcc

perl -e '$s="aaabbcc";$c=()=$s=~s/a/x/g;print"$c\n$s\n"'(s /// g)输出

1
xxxbbcc

我想一次做两件事而不必先匹配:替换并知道替换的数量。显然s /// g不会返回标量上下文中的替换次数 - 与m // g匹配时不同。这可能吗?如果是,怎么样?

perlre,perlvar和perlop没有提供任何帮助(或者我找不到它)。

1 个答案:

答案 0 :(得分:14)

s///确实返回标量上下文中的替换次数。来自perlop(强调补充):

  

<强> S / PATTERN / REPLACEMENT / msixpogce
  在字符串中搜索模式,如果找到,则替换该模式   替换文本的模式和返回的数量   取代。否则返回false(具体来说,   空字符串)。

您的问题是您没有在标量上下文中调用s///。您在列表上下文中调用它,然后在标量上下文中评估赋值(到空列表)。标量上下文中的列表赋值返回表达式右侧生成的元素数。由于s///返回单个值(在列表和标量上下文中),即使s///没有做任何事情,元素的数量也始终为1。

perl -E "$s='aaabbcc'; $c=()=$s=~s/x/y/g; say qq'$c-$s'"  # prints "1-aaabbcc"

要在标量上下文中调用s///,请省略=()=伪运算符。

perl -E "$s='aaabbcc'; $c=$s=~s/a/x/g; say qq'$c-$s'"  # prints "3-xxxbbcc"