扫描方法没有按预期工作

时间:2014-11-07 18:33:49

标签: ruby regex

我有以下字符串:

" lotfan talash nakonid 在jomalat ra bekhanid 正确 zira bi mani hastand 正确 ......"

我需要得到所有出现的"一组字符,然后是Left或Right"。 所以对于上面的字符串我需要得到以下数组:

["lotfan talash nakonid Left", "in jomalat ra bekhanid Right", "zira bi mani hastand Right", ... ]

我尝试使用扫描方法编写它:

str.scan(/.*?(Right|Left)/) # => [["Left"], ["Right"], ["Right"]]

但遗憾的是,括号似乎对scan方法有一些特殊含义。 我们是否有任何方式编写此正则表达式,就像我们在match方法中编写它一样?

3 个答案:

答案 0 :(得分:2)

您也可以使用non-capturing groups,如下所示:

 myString.scan(/.*?(?:Right|Left)/)

documentation(我在上面的评论中链接)解释了发生的事情:

  

如果模式不包含任何组,则每个结果都由匹配的字符串$&组成。如果模式包含组,则每个单独的结果本身就是一个包含每个组一个条目的数组。

答案 1 :(得分:1)

这应该完成你想要做的事情:

string.scan(/(.*?(Right|Left))/).map{|arr| arr.join(" ")}

额外的括号也会在"右边"之前捕获文本。或者"离开"。

然而,非捕捉答案更简洁干净。

答案 2 :(得分:1)

在你的正则表达式中,你有一个捕获组:(Right|Left)。如果存在捕获,String#scan方法将使用捕获而不是整个匹配。您应该将(Right|Left)变为非捕获组:(?:Right|Left)

str = "lotfan talash nakonid Left in jomalat ra bekhanid Right zira bi mani hastand Right ..."
str.scan(/.*?(?:Right|Left)/)
# => => ["lotfan talash nakonid Left", " in jomalat ra bekhanid Right", " zira bi mani hastand Right"]