How many substitutions took place in a Perl s///g?
小例子:
perl -e '$s="aaabbcc";$c=()=$s=~/a/g;print"$c\
$s\
"' (m//g) 输出
而 perl -e '$s="aaabbcc";$c=()=$s=~s/a/x/g;print"$c\
$s\
"' (s///g) 输出
我想同时做这两件事而不必先匹配:替换并知道替换的次数。显然,a s///g 不会返回标量上下文中的替换次数——与 m//g 不同的是匹配匹配。这可能吗?如果是,怎么做?
perlre、perlvar 和 perlop 没有提供任何帮助(或者我只是找不到它)。
- 对于那些通过标题通过网络搜索找到该帖子但问题涉及磁盘上的编辑文件的人:我发布了其他问题 stackoverflow.com/questions/57411792/...,问题是输出需要定向到 STDOUT。
s/// 确实返回在标量上下文中进行的替换次数。来自 perlop(强调添加):
s/PATTERN/REPLACEMENT/msixpogce
Searches a string for a pattern, and if found, replaces that
pattern with the replacement text and returns the number of
substitutions made. Otherwise it returns false (specifically,
the empty string).
您的问题是您没有在标量上下文中调用 s/// 。您在列表上下文中调用它,然后在标量上下文中评估分配(到空列表)。标量上下文中的列表赋值返回表达式右侧产生的元素数。由于 s/// 返回单个值(在列表和标量上下文中),即使 s/// 没有执行任何操作,元素的数量也始终为 1。
1
| perl -E"$s='aaabbcc'; $c=()=$s=~s/x/y/g; say qq'$c-$s'" # prints"1-aaabbcc" |
要在标量上下文中调用 s///,请省略 =()= 伪运算符。
1
| perl -E"$s='aaabbcc'; $c=$s=~s/a/x/g; say qq'$c-$s'" # prints"3-xxxbbcc" |
- 实际上,他并没有在标量上下文中评估该列表。那是不可能的。他在标量上下文中评估了列表分配。
-
@daotoad:谢谢,我知道这不太对,但术语让我一时不知所措。 Tangent:为什么没有更多的人使用他们的编辑能力来修复这样的细节?
-
我无法反思他人的动机,但我不会以任何改变意图或意义的方式编辑他人所写的内容。例如,有些人热衷于相信 Perl 中存在"标量上下文中的列表",如果你是这些人中的一员,我会非常冒犯你的话:否认你的(错误的和假定的)信念。也有我的理解有误的情况,换个帖子就会出错。由于这些原因,我更愿意指出错误而不是"修复"它们。 YMMV
-
在 Perl 标记下,对问题中的"错误"进行了很多修复,这些问题会改变问题以便它自己回答。
-
回想起来,我的问题相当尴尬。不知道为什么我没有在明显的文档中找到它……我想这是漫长的一天。显然,我认为 m// 和 s/// 在标量或列表上下文中的评估应该表现相似,这是错误的。有人关心我为什么"列表的标量评估"是错误的吗?因为即使是 \\'Programming Perl\\' 也正是使用该表达式(第 3 版,2.8.2)。
-
@musikk,每个人都会对文档中有一个简单答案的问题感到沮丧。如果您指的是 PP books.google.com/... 中的这一部分 - 那就是在谈论列表文字。列表文字实际上是一堆由中缀逗号运算符分隔的标量。在标量上下文中,逗号关联左侧并返回右侧,这意味着标量上下文中的列表文字计算为列表文字中的最后一项。请参阅 perlmonks.org/?node_id=719099 进行激烈讨论。
-
@daotoad:我再次混淆了列表和数组......尽管偶尔使用 Perl 几年,但我仍然没有完全掌握这一点。我将不得不阅读。还要感谢 perlmonks 的链接,这个讨论听起来很有趣。适合安静的周五晚上。非常感谢您的帮助(你们所有人)。