用逗号分隔字符串,忽略括号中的逗号,括号,括号,引号

时间:2017-11-02 10:56:37

标签: regex postgresql

我正在尝试拆分以逗号分隔的列表。我想忽略使用正则表达式括号,括号,大括号和引号中的逗号。更确切地说,我想在postgres POSIX regexp_split_to_array中尝试这样做。

我对正则表达式的了解并不是很好,通过搜索堆栈溢出,我能够得到一个部分解决方案,如果它不包含嵌套的括号,括号,大括号,我可以拆分它。这是正则表达式:

,(?![^()]*+\))(?![^{}]*+})(?![^\[\]]*+\])(?=(?:[^"]|"[^"]*")*$)

测试用例:

0, (1,2), (1,2,(1,2)) [1,2,3,[1,2]], [1,2,3], "text, text (test)", {a1:1, a2:3, a3:{a1=1, s2=2}, a4:"asasad, sadsas, asasdasd"}

Here is the demo

问题是在(1,2,(1,2))中,如果有嵌套的括号,则前2个逗号匹配。

1 个答案:

答案 0 :(得分:0)

尽管正则表达式不是最好的方法,但这里有一个递归匹配的解决方案:

(?>(?>\([^()]*(?R)?[^()]*\))|(?>\[[^[\]]*(?R)?[^[\]]*\])|(?>{[^{}]*(?R)?[^{}]*})|(?>"[^"]*")|(?>[^(){}[\]", ]+))(?>[ ]*(?R))*

如果我们把它分解,里面有一个组,里面有一些东西,后面是更多相同类型的匹配,用可选的空格分隔。

(?>               <---- start matching
   ...            <---- some stuff inside
)                 <---- end matching
(?>
   [ ]*           <---- optional spaces
   (?R)           <---- match the entire thing again
)*                <---- can be repeated

从您的示例 0, (1,2), (1,2,(1,2)) [1,2,3,[1,2]], [1,2,3],... 中,我们希望匹配:

0
(1,2)
(1,2,(1,2)) [1,2,3,[1,2]]
[1,2,3]
...

对于第三个匹配,里面的东西会匹配(1,2,(1,2))[1,2,3,[1,2]],它们之间用空格分隔。

里面的东西是一系列的选项:

(?>
   (?>...)|       <---- will match balanced ()
   (?>...)|       <---- will match balanced []
   (?>...)|       <---- will match balanced {}
   (?>...)|       <---- will match "..."
   (?>...)        <---- will match anything else without space or comma
)

以下是选项:

\(                <---- literal (
  [^()]*          <---- any number of chars except ( or )
  (?R)?           <---- match the entire thing optionally
  [^()]*          <---- any number of chars except ( or )
\)                <---- literal )
\[                <---- literal [
  [^[\]]*         <---- any number of chars except [ or ]
  (?R)?           <---- match the entire thing optionally
  [^[\]]*         <---- any number of chars except [ or ]
\]                <---- literal ]
{                 <---- literal {
 [^{}]*           <---- any number of chars except { or }
 (?R)?            <---- match the entire thing optionally
 [^{}]*           <---- any number of chars except { or }
}                 <---- literal }
"                 <---- literal "
 [^"]*            <---- any number of chars except "
"                 <---- literal "
[^(){}[\]", ]+    <---- one or more chars except comma, or space, or these: (){}[]"

请注意,这不匹配逗号分隔的列表,而是匹配此类列表中的项目。在上面的最后一个选项中排除逗号和空格会导致它在逗号或空格处停止匹配(我们明确允许重复匹配之间的空格除外)。