繁体   English   中英

负面看中间的东西背后

[英]Negative look behind with something in the middle

我有两种类型的字符串。 如果一个字符串包含foo first和later bar ,则不应该触及它。 如果它只包含bar ,那么bar应该用qux替换。

  • 不应该触及"sometext foo someothetext bar somethirdtext"
  • "sometext bar someothetext" => "sometext qux someothetext"

看起来我需要使用负面外观,但我无法让它正常工作。 目前,我有一个表达:

str.gsub! (/(?<!foo)(.*)bar/), '\1qux'

但是,它将bar替换为两个字符串中的qux 我有一种感觉.*搞砸了。 我无法找到背后的示例,其中群组后面的内容不会立即出现在匹配群组之前。

如果你可以使用可变长度的lookbehinds,你可以用'qux'替换/(?<!foo.*)bar/匹配。

如果不支持可变长度的lookbehinds,你可以真正使用lookbehind因为你无法知道启动lookbehind来找到foo 以下是如何通过前瞻来做到这一点:

str.gsub!  (/\A(((?!foo).)*)bar/m), '\1qux'

说明:

\A           # match at the start of the string
(            # start capture group 1
  (            # start capture group 2, repeat 0 or more times
    (?!foo)      # fail if 'foo' can match here
    .            # match a single character
  )*           # end capture group 2
)            # end capture group 1
bar          # match 'bar'

这会在每个字符处执行负向前瞻(?!foo) ,直到我们匹配bar ,因此它不会匹配foobar之前的字符串。

字符串开头的锚点是必要的,因为如果你可以从字符串的中间开始,它将在foof之后立即开始匹配。 使用多行选项以便. 字符将匹配换行符,不确定这是否对您正在做的事情是必要的。

你可以这样做:

if str.include? "foo"
  str = str.slice(0, str.index("foo")-1).sub("bar","qux") + str.slice(str.index("foo")-1, str.length)
else
  str = str.sub("bar","qux")
end

它将在“foo”的第一个实例之前替换任何“bar”,然后在其余的字符串上添加

也许你可以使用一个flag来跟踪前面是否有foo

flag = false
"sometext foo someothetext bar somethirdtext"
.gsub(/(foo)|bar/){flag = true if $1; flag ? $& : "qux"}
# => "sometext foo someothetext bar somethirdtext"

flag = false
"sometext bar someothetext"
.gsub(/(foo)|bar/){flag = true if $1; flag ? $& : "qux"}
# => "sometext qux someothetext"

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM