Ruby regex to match multiple occurrences of a pattern
I'm looking to create a ruby ββregex to match multiple occurrences of a pattern and return them to an array. The template is simple: [[. +]]. That is, two left brackets, one or more characters, and then two right brackets.
This is what I did:
str = "Some random text[[lead:first_name]] and more stuff [[client:last_name]]"
str.match(/\[\[(.+)\]\]/).captures
The regex above doesn't work because it returns this:
["lead:first_name]] and another [[client:last_name"]
When I wanted it was the following:
["lead:first_name", "client:last_name"]
I thought that if I used a group without registration, then for sure it should solve the problem:
str.match(/(?:\[\[(.+)\]\])+/).captures
But the uncaptured group returns the same exact wrong conclusion. Any idea on how I can solve my problem?
source to share
Try this
:
=> 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"]]
source to share
The problem with your regex is that the portion .+
is "greedy", which means that if the regex matches both less and most of the string, it will grab most of it ( more about greedy regex ).
In Ruby (and most regex syntaxes), you can qualify your quantifier +
with ?
to make it non-living. This way your regex will become /(?:\[\[(.+?)\]\])+/
.
However, you will notice that this still does not work for what you want to do. Ruby capture groups just don't work inside a repeating group. For your problem, you need to use scan
:
"[[a]][[ab]][[abc]]".scan(/\[\[(.+?)\]\]/).flatten
=> ["a", "ab", "abc"]
source to share