Imri Barr
Imri Barr

Reputation: 1065

Match function parameters

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

Answers (3)

user2705585
user2705585

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

riteshtch
riteshtch

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

strippenzieher
strippenzieher

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

Related Questions