Reputation: 1065
I've been trying to create a regex that matches function parameters.
Here's the full sample (with debug mode): https://regex101.com/r/vM7xN1/1
The regex I currently have is this one: \(([^,\s\)]+)(?:\s*,\s*([^,\s\)]+))*\)
And the match results I'm trying to achieve:
1. someFunc(param) => ['param']
2. someFunc(param, param2) => ['param', 'param2']
3. someFunc(param, param2, param3) => ['param', 'param2', 'param3']
4. someFunc(param, param2, param3, param4) => ['param', 'param2', 'param3', 'param4']
For some reason, this matches only 1, 2 functions correcly. And in functions 3 and 4 it will only match the first param and the last param.
Why is it skipping the params between the first and the last?
Edit: Additional tests:
'myFunction(param1, param2, param3)'.match(/(([^,\s)]+)(?:\s*,\s*([^,\s)]+))*)/) => ["(param1, param2, param3)", "param1", "param3"]
When trying without the non-capturing group I get this:
'myFunction(param1, param2, param3)'.match(/(([^,\s)]+)(\s*,\s*([^,\s)]+))*)/) => ["(param1, param2, param3)", "param1", ", param3", "param3"]
Any help would be great.
Thanks!
Upvotes: 2
Views: 1763
Reputation:
It's not actually skipping anything.
Let's breakdown your regex and try to understand what each part is doing in case of third function. someFunc(param, param2, param3)
.
Regex: \(([^,\s\)]+)(?:\s*,\s*([^,\s\)]+))*\)
([^,\s\)]+)
is matching param
and capturing it in group.
(?:\s*,\s*([^,\s\)]+))
matches all the , string
instances which in your case is , param2, param3
.
So the complete string matched is
(param
, param2, param3)
But as you have used ([^,\s\)]+)
the last sub-group captured is param3
which is also a part of ,param2, param3
. Which is also visible in Regex101's Match Information.
Upvotes: 1
Reputation: 8769
Just use a simple regex to get everything between the round brackets and split on comma:
>"someFunc(param, param2, param3, param4)".match(/(?:\()(.+)+(?:\))/)
["(param, param2, param3, param4)", "param, param2, param3, param4"]
>"someFunc(param, param2, param3, param4)".match(/(?:\()(.+)+(?:\))/)[1].split(/[\s,]+/)
["param", "param2", "param3", "param4"]
Edit:
We can also filter out empty elements(if any) like this:
>"someFunc( param , param2 , param3 )".match(/(?:\()(.+)+(?:\))/)[1].split(/[\s,]+/)
["", "param", "param2", "param3", ""]
>"someFunc( param , param2 , param3 )".match(/(?:\()(.+)+(?:\))/)[1].split(/[\s,]+/).filter(function(e){return e})
["param", "param2", "param3"]
Upvotes: 2
Reputation: 316
As noob already explained, you are matching everything but your capture group stores only the last match. See http://www.rexegg.com/regex-capture.html#spawn_groups on generating new capturing groups for further information.
Upvotes: 1