dthree
dthree

Reputation: 20780

Tricky regex parse on key value pairs

I have spent over an hour messing with Regex patterns in order to get a find-and-replace on a complex string working right.

I need to convert a string like this:

foo a='b' c="d and e" wombat=true a fizz='buzz' "hello='goodbye'"

and normalize it into this:

foo "a='b'" "c='d and e'" "wombat='true'" a "fizz='buzz'" "hello='goodbye'"

In essence:


So far I'm playing with a Regex on the order of:

str = str.replace(/([a-zA-Z0-9]*)=("(.*?)"|'(.*?)')/g, '"$1=\'$2\'');

However, this has a ton of problems.

Is there any single-replace solution to this?

Upvotes: 3

Views: 330

Answers (2)

Tomalak
Tomalak

Reputation: 338326

Substituting

/(['"]?)(\w+)=(?:(['"])((?:(?!\3).)*)\3|(\S+))\1/g

with

"$2='$4$5'"

gives the wanted

foo "a='b'" "c='d and e'" "wombat='true'" a "fizz='buzz'" "hello='goodbye'"

The expression breaks down as follows:

(['"]?)            # group 1: either single or double quote, optional
(\w+)              # group 2: word characters (i.e. the "key")
=                  # a literal "="
(?:                # non-capturing group
  (['"])           #   group 3: either single or double quote
  (                #   group 4 (quoted value): 
    (?:(?!\3).)*   #     any character that's not the same as group 3
  )                #   end group 4
  \3               #   the quote from group 3  
  |                #   or...
  (\S+)            #   group 5 (non-quoted value, no spaces)
)                  # end non-capturing group
\1                 # whatever group 1 had, for good measure

Upvotes: 6

Rahul
Rahul

Reputation: 3509

The below regex will fulfill your requirements:

"?(\w+)='?([\w]+)'?"?|"?(\w+)="([\w\s]+)""? 

with substitution as:

"$1$3='$2$4'"

Demo

Upvotes: 1

Related Questions