棘手的正则表达式解析键值对

时间:2016-03-01 07:42:57

标签: javascript regex

我花了一个多小时搞乱正则表达式模式,以便在复杂的字符串上运行find-and-replace

我需要像这样转换一个字符串:

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

并将其标准化为:

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

本质上:

  • 每个key/value对都应该用双引号括起来,并将值用单引号括起来,而不管它们之前是如何包装的。

  • 多行距离值必须先用单引号或双引号括起来才能包含"包含"作为一种价值。

到目前为止,我正按照以下顺序玩正则表达式:

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

然而,这有很多问题。

是否有任何单一替代解决方案?

2 个答案:

答案 0 :(得分:6)

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

"$2='$4$5'"

给出了想要的

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

表达式分解如下:

(['"]?)            # 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

答案 1 :(得分:1)

以下正则表达式将满足您的要求:

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

替换为:

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

SimpleDateFormat