Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regex for complex delimited string with multiple parse patterns

Tags:

java

regex

groovy

I have the following string:

def str='prop1: value1, prop2: value2;value3, prop3:"test:1234, test1:23;45, test2:34;34", prop4: "test1:66;77, 888"'

what I want to end up with is the following list of pairs

prop1: value1
prop2: value2;value3
prop3: test:1234, test1:23;45, test4:34;34
prop4: test, 66;77, 888

I figure if I can first parse and strip out props3 and 4, then I can simply split on comma for the rest of the string. but having a problem with being able to get a match for prop 4

The following is the code and regex I have tried so far. Commented out in the code are various regex I have tried but have not been able to extract the last prop4

  def str='prop1: value1, prop2: value2;value3, prop3:"test:1234, test1:23;45, test4:34;34", prop4: "test, 66;77, 888"'
  //def regex = /(\w+):"(.*)"[,\s$]/
  //def regex = /(\w+):"(.*)"[,|\s|$]/
  def regex = /(\w+):"(.*)"[,\s]|$/
  def m = (str =~ regex)
  (0..<m.count).each{
    println("${m[it][1]}=${m[it][2]}")
  }

This returns:

prop3=test:1234, test1:23;45, test2:34;34
null=null

What am I missing here?

(Also, is there a way to parse all this with just a single regex pass as opposed to my approach described above..regex first, then split?)

like image 447
mike01010 Avatar asked Aug 02 '26 11:08

mike01010


2 Answers

Basee on your give example data, following regex would work:

\b(\w+):\s*(\"[^\"]*\"|[^,\"]*)

RegEx Demo

RegEx Demo:

  • \b: Word boundary
  • (\w+): Capture group #1 t match 1+ word characters
  • :: Match a :
  • \s*: 0 or more whitespaces
  • (: Start capture group #2
    • \"[^\"]*\": Match a quoted text
    • |: OR
    • [^,\"]*: Match 0 or more of any char that is not , and "
  • ): End capture group #2
like image 125
anubhava Avatar answered Aug 05 '26 11:08

anubhava


In case you are ok to have different capturing groups for different matches then please try following regex. Here is the Online Demo for used regex.

(.*?),.*?\s(.*?),\s(.*?)"((?:.*?,){2}\s.*?)",\s(.*?:)\s"(.*?)"

Explanation: Adding detailed explanation for above regex.

(.*?)            ##Creating 1st capturing group using Lazy match.
,.*?\s           ##using lazy match till next occurrence of comma followed by again a lazy match till space occurrence.
(.*?)            ##Creating 2nd capturing group which does lazy match.
,\s              ##Till next occurrence of comma followed by a space.
(.*?)"           ##Creating 3rd capturing group just before next occurrence of " here.
(                ##Creating 4th capturing group here, which has:
  (?:.*?,){2}    ##In a non-capturing group matching till next occurrence of comma in Lazy match and matching 2 occurrences of it.
  \s.*?          ##Followed by a space and again a lazy match
)                ##Closing 4th capturing group here.
",\s             ##Matching ", followed by space here.
(.*?:)           ##Creating 5th capturing group with lazy match till next occurrence of : here.
\s"              ##Matching space followed by " here.
(.*?)            ##Creating 6th capturing group with a mazy match in it just before next occurrence of " here.
"                ##matching " here.
like image 40
RavinderSingh13 Avatar answered Aug 05 '26 12:08

RavinderSingh13



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!