我希望构建一个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
但非捕获组返回相同的错误输出。关于如何解决我的问题的任何想法?
答案 0 :(得分:6)
你的正则表达式的问题是.+
部分是“贪婪的”,这意味着如果正则表达式匹配字符串的较小和较大部分,它将捕获较大的部分(more about greedy regexes )。
在Ruby(以及大多数正则表达式语法)中,您可以使用+
限定?
量词,使其变得非贪婪。所以你的正则表达式会变成/(?:\[\[(.+?)\]\])+/
。
但是,您会注意到这仍然不适用于您想要做的事情。 Ruby捕获组在重复组内部不起作用。对于您的问题,您需要使用scan
:
"[[a]][[ab]][[abc]]".scan(/\[\[(.+?)\]\]/).flatten
=> ["a", "ab", "abc"]
答案 1 :(得分:3)
=> str.match(/\[\[(.*)\]\].*\[\[(.*)\]\]/).captures
=> ["lead:first_name", "client:last_name"]
=> 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"]]