jtabuloc
jtabuloc

Reputation: 2535

How to split string by comma within parenthesis but not those on double quote

How can I capture all parameter on sample string using Regex? I tried to use (\@\w+|\w+) pattern on https://regex101.com/ but it returns all words on sample string which is not what I expect.

.selector(@background, height, font "font-family, font family", @width : 10px, "red");

expected output should capture 5 parameters:

 1. @background
 2. height
 3. font "font-family, font family"
 4. @width : 10px
 5. "red"

I'm having difficulties on combining regular expression and it took me an hour to figure it out that is why I decide to ask for a help.

Upvotes: 3

Views: 777

Answers (3)

Bentoy13
Bentoy13

Reputation: 4966

Here is a all-in-one regex:

/(?<=[,\(])(?:\s*)([^,"]*(?<dq>")?(?(dq)[^"]+"[^\(\),]*))(?:\s*)/g

Explanation:

  • a parameter is something either after a comma or an opening bracket -> control this by a positive lookbehind (?<=[,\(])
  • match but don't take any extra whitespace -> (?:\s*) outside the caputring group (nicer).
  • In the capturing group:
    • begin by matching anything but comma and double quote.
    • if a double quote is encountered, match anything till another double quote is matched.

See on https://regex101.com/r/pC9fB6/1 the results.

Note: dystroy points out in a comment behind that lookbehind assertion is not supported by all regex engines (e.g. JavaScript). A possible solution is to put the character class [,\(] of the lookbehind assertion inside the non-capturing group of whitespace: (?:[,\(]\s*). The result is almost the same, the numbered captured matches are exactly the same.

Upvotes: 0

vks
vks

Reputation: 67968

^.*?\(|,(?=(?:[^"]*"[^"]*")*[^"]*$)|\).*$

You can split by this and remove empty string from the result.See demo.

https://regex101.com/r/nD5jY4/6

Upvotes: 0

Denys S&#233;guret
Denys S&#233;guret

Reputation: 382170

First, I would extract the interesting part between the parenthesis, then I would read the internal parameters:

var args = str.match(/\(([^\)]+)\)/)[1].match(/[^,"]+("[^"]+")*/g)

Result:

enter image description here

The idea of the second part ([^,"]+("[^"]+")*) is to explicitly include parts between quotes.

Upvotes: 2

Related Questions