我有一个像xfooxbar
这样的字符串,想要使用scan
将其拆分为['foo','bar']。 (在有人问为什么不使用split
之前,真正的例子更复杂,我需要获得边界字符串,这会丢弃丢弃。我问这个问题是为了更多地了解扫描的工作原理或者如果有类似的选择,我发现这比我预期的更难。)
这不起作用,因为它会一直扫描直到字符串结束:
"xfooxbar".scan(/(?:x)(.*)/)
> [["fooxbar"]]
问题是扫描在找到下一个模式时不会神奇地停止扫描,并且使用(。*?)使其非贪婪只会使其为空,因为没有端点。所以我们可以添加一个端点作为下一个匹配:
"xfooxbar".scan(/(?:x)(.*)(?:x)/)
> [["foo"]]
问题是扫描显然与字符串中的每个可能模式都不匹配,因为它将指针保持在当前位置并且不会回溯。所以它在第二个边界上匹配,并将从那里恢复扫描(?:对此没有影响)。
答案 0 :(得分:2)
使用下面的正面lookbehind断言。
irb(main):001:0> "xfooxbar".scan(/(?<=x)[^x]*/)
=> ["foo", "bar"]
(?<=x)
肯定的外观断言,匹配必须以字母x
开头。[^x]*
匹配任何字符,但不匹配x
,零次或多次。 答案 1 :(得分:1)
除非我遗漏了一些不能用简单的非x正则表达式做到的事情吗?
(我已经扩展了原始字符串以证明这一点)
pry(main)> "nonexfooxbarxgreedy\ngreedyxgoose".scan(/x([^x]*)/)
=> [["foo"], ["bar"], ["greedy\ngreedy"], ["goose"]]