Regex 使用perl替换除最后一次之外的所有事件

Regex 使用perl替换除最后一次之外的所有事件,regex,perl,substitution,regex-greedy,Regex,Perl,Substitution,Regex Greedy,我有一个字符串,上面写着“a/b/c/d/e”,我想替换除最后一个/之外的所有内容。i、 e我的输出应该是a.b.c.d/e 如何修改替换命令s/\//./g以执行相同的操作?还要注意,层次结构并不总是有4“/”。它可以是任何数字。替换字符串下有/的所有/;因此,这不包括最后一个/ perl -wE'$_ = q(a/b/c/d/e); s{/(?=.*?/)}{.}g; say' 这使用,(?=…)来断言进一步向下(在*?之后)存在/,而不消耗任何内容 另一种方法是使用否定字符类模式进行捕

我有一个字符串,上面写着
“a/b/c/d/e”
,我想替换除最后一个
/
之外的所有内容。i、 e我的输出应该是
a.b.c.d/e


如何修改替换命令
s/\//./g
以执行相同的操作?还要注意,层次结构并不总是有4“
/
”。它可以是任何数字。

替换字符串下有
/
的所有
/
;因此,这不包括最后一个
/

perl -wE'$_ = q(a/b/c/d/e); s{/(?=.*?/)}{.}g; say'
这使用,
(?=…)
来断言进一步向下(在
*?
之后)存在
/
,而不消耗任何内容


另一种方法是使用否定字符类模式进行捕获(然后将其放回字符串中),并在前瞻中仅使用固定字符串
/

s{/([^/]*)(?=/)}{.$1}g;
上面的第一种方法是使用
/
匹配并对其余部分进行前瞻,结果证明速度更快。可能的原因是
([^/]*)
方法中的捕获(它必须将其复制回字符串中),其中第一种方法执行单字符覆盖(
*?
不会回溯)

基准测试:在v5.10.1和v5.27.2(台式机)下加快126%,在v5.16.1(新服务器)下加快110%。使用4-10个字符长的字符串测试四个路径组件


感谢您注意到这一点,并对比较进行了提示和评论。

是否更有效<代码>s{/([^/]*)(?=/)}{.$1}g非常感谢。上述两种选择似乎都有效。我继续写这个{/([^/]*)(?=/)}{.$1}g;,因为它看起来generic@ikegami结果不是(在我的基准测试中),谢谢你,补充道。我猜原因是:
[^/]
一个还必须复制它捕获的内容,而另一个则执行单个字符覆盖(并且
*?
不会回溯)。我正在用更长的字符串测试更多内容,以防万一。@zdim,捕获添加时间。我不知道它是否会比你的两倍匹配字符串。也可能取决于设备的大小string@ikegami更新了,带有注释和更长的路径组件——它在不同的perl和机器上更加一致。谢谢,这很有趣。