Reputation: 20780
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:
Every key/value
pair should be wrapped in double-quotes, with the value wrapped in single-quotes, regardless of how they were wrapped before.
A multi-spaced value must be wrapped in single or double quotes before in order to be "included" as a value.
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
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