How can I match the comma between each key:value pair EXCEPT to exclude the last comma match? And please me know if you have a cleaner regex as mine seems a little messy. I am new to writing regex.
I need to pattern match this format and they need to be map string:string {\"key1\":\"val1\",....N} or {"key1":"val1",....N}
Example
{\"key1\":\"val1\",\"key2\":\"val2\",\"k3\":\"v3\",\"k4\":\"v4\"}
What I have for my regex:
^[{]((["]|[\\]["])[a-zA-Z0-9] (["]|[\\]["])[:](["]|[\\]["])[a-zA-Z0-9] (["]|[\\]["])[,]) [}]$
What my match is - I do not want the last comma: {"key1":"val1","key2":"val2","k3":"v3","k4":"v4",}
CodePudding user response:
Its usually done by requiring the first Key/Val pair, then making all the others
optional with a prepended separator ,
^{\\?"[a-zA-Z0-9] \\?":\\?"[a-zA-Z0-9] \\?"(?:,\\?"[a-zA-Z0-9] \\?":\\?"[a-zA-Z0-9] \\?")*}$
https://regex101.com/r/cqJk8q/1
^
{
\\? " [a-zA-Z0-9] \\? ": \\? " [a-zA-Z0-9] \\? "
(?:
, \\? " [a-zA-Z0-9] \\? ": \\? " [a-zA-Z0-9] \\? "
)*
}
$
CodePudding user response:
Instead of ending with
[,]) [}]$
end with
(,(?!$)|}$)) $
See live demo.
Also, some simplification you can do:
[:]is identical to just:, etc for all like this(["]|[\\]["])is identical to\\?"[a-zA-Z0-9]is almost equivalent to\w(\walso allows the underscore - if that's a problem, just leave[a-zA-Z0-9])
So, your whole regex could be refactored to:
^\{(\\?"\w \\?":\\?"\w \\?"(,(?!$)|}$)) $
Your regex however allow mismatched escaping, eg
`{\"key1": "value1"}`
`{"key1": "value1\"}`
To fix that, capture the optional backslash and use a back reference to it on the other end so they must be balanced:
^\{(?:(\\?)"\w \1":(\\?)"\w \2?"(,(?!$)|}$)) $
