"/foo/bar" irb(main):017:0> source.gs-6ren">
gpt4 book ai didi

Ruby gsub 正则表达式意外行为

转载 作者:数据小太阳 更新时间:2023-10-29 08:22:11 25 4
gpt4 key购买 nike

我以为我很了解正则表达式,但这让我感到困惑:

irb(main):016:0> source = "/foo/bar"
=> "/foo/bar"
irb(main):017:0> source.gsub( /[^\/]*\Z/, "fubar" )
=> "/foo/fubarfubar"

据我所知,/[^\/]*\Z/有一个独特的扩展来匹配 bar因此应该导致 /foo/fubar .我完全看不出为什么我得到 fubarfubar作为替代品。

如果我调用 sub,替换工作正常而不是 gsub ,所以这不是解决问题的问题,而是揭露我对 gsub 的误解的问题.

最佳答案

你需要使用 sub 因为你只需要在字符串的末尾替换一次:

source.sub( /[^\/]*\Z/, "fubar" )
^^^

参见 IDEONE demo

问题很可能出在匹配项的收集方式上,因为您的模式匹配的是一个空字符串,尽管在最后,最后一个 null 也可以被视为第二个匹配项。这不仅是 Ruby 问题,许多其他语言中也存在类似的错误。

所以,实际上,这就是正在发生的事情:

  • [^\/]*\Z 模式匹配 bar 并将其替换为 foobar
  • 正则表达式索引在字符串的末尾 - 是的,有一个 NULL,但 Ruby 仍然将其视为要处理的有效“字符串”,并且
  • [^\/]*\Z 匹配 NULL,并添加另一个 foobar

如果需要使用gsub,请将允许匹配0个字符的*量词替换为需要至少出现1次量词的+子模式,避免匹配长度为 0 的字符串:

source.gsub( /[^\/]+\Z/, "fubar" )
^

经验法则:避免在 Regex 替换方法中使用匹配空字符串的正则表达式!

关于Ruby gsub 正则表达式意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37593202/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com