正则表达式:用括号分割忽略引号内的嵌套括号

时间:2014-05-23 23:44:52

标签: java regex

我的程序将SQL VALUES多行字符串解析为单行字符串数组。

典型的输入字符串如下所示:

(11,'-1','Service A (nested parentheses)','en') (22,'-2','Service B (nested parentheses)','en')

期望的输出:

  • 第1组:11,'-1','Service A (nested parentheses)','en'
  • 第2组:22,'-2','Service B (nested parentheses)','en'

我试过跟随regexp,只有部分运气:

\(('.*?'|.*?)\)

在regexp中处理此问题的正确方法是什么?

编辑:

  • 目标平台是Java 6/7
  • 没有必要用新行替换括号 - 仅捕获组

3 个答案:

答案 0 :(得分:2)

编辑:在您对表情符号的评论之后,我会建议另一种方法:

(?<=\()(?:'[^']*'|[,\s]+|\d+)+(?=\))

demo。这假定您的令牌是由单引号或数字分隔的字符串。这是对的吗?

原始答案

有一个潜在的嵌套级别,这将适用于大多数正则表达式,包括Java:

(?<=\()(?:[^()]+|\([^)]+\))+

请参阅demo

它是如何运作的?

  1. lookbehind断言前一个字符是左括号(
  2. 具有+量词的非捕获组匹配以下一项或多项:(i)任何未打开或关闭括号的字符,或|(ii)完整{{1 }}
  3. 如果要确保容器是平衡的,请在末尾添加一个前瞻:

    (parenthesized expressions)

答案 1 :(得分:1)

pattern.compile("\\(((?:'[^']*'|[^'\\(\\)]+)+)\\)");

RegexPlanet点击Java链接。

正则表达式的内容是'[^']*'|[^'\(\)] - 任何由单引号包围的字符系列或任何字符串,不包括单引号和圆括号。这避免了必须使用环顾四周,虽然Casimir et Hippolyte建议的环顾可能实际上更有效(我不是特别熟悉Java环顾四周的性能方面)。

答案 2 :(得分:0)

有警告:

/\(.*\)/\1/

将删除周围的括号,

/\) \(/\r/g

将按照示例

添加换行符

注意事项:

  • 此正则表达式采用通用形式,因为您未指定哪个正则表达式实现
  • 仅当输入与您的示例
  • 非常匹配时才有效