Ruby 用中间的东西向后看
我有两种类型的字符串。如果字符串首先包含Ruby 用中间的东西向后看,ruby,regex,Ruby,Regex,我有两种类型的字符串。如果字符串首先包含foo,然后包含bar,则不应触摸该字符串。如果它只包含条,则条,应替换为qux “sometext foo someothetext bar somethirdtext”不应触摸 “sometext bar somethetext”=>“sometext qux somethetext” 看起来我需要使用“反向向后看”,但我无法使其正常工作。目前,我有一个表达: str.gsub! (/(?<!foo)(.*)bar/), '\1qux' s
foo
,然后包含bar
,则不应触摸该字符串。如果它只包含条
,则条
,应替换为qux
不应触摸“sometext foo someothetext bar somethirdtext”
=>“sometext bar somethetext”
“sometext qux somethetext”
str.gsub! (/(?<!foo)(.*)bar/), '\1qux'
str.gsub!(/(?
但是,它将两个字符串中的条
替换为qux
。我感觉*
会把事情搞砸。我无法找到一个查找后面的示例,其中查找后面的组不会立即位于匹配的组之前。如果可以使用可变长度的查找后面,您可以只替换的匹配项/(?带有“qux”
如果不支持可变长度lookbehind,您实际上可以使用lookbehind,因为您不知道开始查找foo
的位置。以下是使用lookbehind的方法:
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
,因此它不会匹配foo
位于bar
之前的字符串
到字符串开头的锚是必要的,因为如果你可以在字符串的中间开始,在 Foo后,立即开始匹配。多行选项被使用,以便<代码> ./COD>字符将匹配断线,不确定这是否对你所做的是必要的。
你可以这样做:
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”,然后固定字符串的其余部分也许您可以使用标志
来跟踪前面是否有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"