ruby正则表达式匹配多次出现的模式

时间:2015-01-10 21:48:39

标签: ruby regex

我希望构建一个ruby正则表达式来匹配模式的多次出现并将它们返回到数组中。模式很简单:[[。+]]。也就是说,两个左括号,一个或多个字符,后跟两个右括号。

这就是我所做的:

str = "Some random text[[lead:first_name]] and more stuff [[client:last_name]]"
str.match(/\[\[(.+)\]\]/).captures

上面的正则表达式不起作用,因为它返回:

["lead:first_name]] and another [[client:last_name"]

当我想要的是这个时候:

["lead:first_name", "client:last_name"] 

我想如果我使用非捕获组,肯定它应该解决问题:

str.match(/(?:\[\[(.+)\]\])+/).captures

但非捕获组返回相同的错误输出。关于如何解决我的问题的任何想法?

2 个答案:

答案 0 :(得分:6)

你的正则表达式的问题是.+部分是“贪婪的”,这意味着如果正则表达式匹配字符串的较小和较大部分,它将捕获较大的部分(more about greedy regexes )。

在Ruby(以及大多数正则表达式语法)中,您可以使用+限定?量词,使其变得非贪婪。所以你的正则表达式会变成/(?:\[\[(.+?)\]\])+/

但是,您会注意到这仍然不适用于您想要做的事情。 Ruby捕获组在重复组内部不起作用。对于您的问题,您需要使用scan

"[[a]][[ab]][[abc]]".scan(/\[\[(.+?)\]\]/).flatten
    => ["a", "ab", "abc"]

答案 1 :(得分:3)

Try this

 => str.match(/\[\[(.*)\]\].*\[\[(.*)\]\]/).captures
 => ["lead:first_name", "client:last_name"] 

With many occurrences

 => str
 => "Some [[lead:first_name]] random text[[lead:first_name]] and more [[lead:first_name]] stuff [[client:last_name]]" 
 => str.scan(/\[(\w+:\w+)\]/)
 => [["lead:first_name"], ["lead:first_name"], ["lead:first_name"], ["client:last_name"]]