Home > OS >  How can I exclude the last regex match check on this regex?
How can I exclude the last regex match check on this regex?

Time:02-04

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 (\w also 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?"(,(?!$)|}$)) $

See live demo (with all input varieties).

  •  Tags:  
  • Related