在Java中使用RegEx,如何捕获由双引号分隔的组,不包括用双引号括起来的组?

时间:2015-01-12 08:10:11

标签: java regex

示例:

abc | efg || $something("arg 1", "arg 2||(a|b)") || 123

或没有空格

abc|efg||$something("arg 1", "arg 2||(a|b)")||123

需要什么RegEx模式才能获得以下组:

abc | efg
$something("arg 1", "arg 2||(a|b)")
123

共3组。

另一个例子:

"abc || efg" || 123

应该给我2组

"abc || efg"
123

基本上它通过双管切割或拆分字符串,但不包括双引号内的双管。

我失败的尝试如下:

+。?(= \ |?\ |)| *。

\&#34 + \" |。?。?(?= \ | \ |)|。* +

5 个答案:

答案 0 :(得分:5)

这就是我要做的,正则表达式:

(?:^|\|\|)(?:(?!\|\|)(?!").|"(?:[^"\\]|\\.)*")*

Regex101演示 here 。您可以看到右侧的匹配项,我将它们放在捕获组中以省略||,您可以使用Java中的m.group(1)来获取它们。 Java不是我的强项,但它应该是这样的:

String s ="abc | efg || $something(\"arg 1\", \"arg 2||(a|b)\") || 123";   
String patternStr="(?:^|\\|\\|)(?:(?!\\|\\|)(?!\").|\"(?:[^\"\\\\]|\\\\.)*\")*";
Pattern p = Pattern.compile(patternStr);
Matcher m = p.matcher(s);
while (m.find()){
    System.out.println(m.group(1));
}

修改:已经意识到您可能希望接受"$something("arg with \" in it", "arg 2||(a|b)"这样更新正则表达式。

已添加:结合波希米亚的解决方案,如果更容易,您可以分开:

\|\|(?=(?:(?:(?:[^"\\]|\\.)*"){2})*[^"]*$)

Regex101 或在Java中:

String[] parts = str.split("\\|\\|(?=(?:(?:(?:[^\"\\\\]|\\\\.)*\"){2})*[^\"]*$)");

答案 1 :(得分:1)

\|\|(?=(?:[^"]*"[^"]*")*[^"]*$)

由此分开。参见演示。

https://regex101.com/r/sH8aR8/47

答案 2 :(得分:0)

如果可以接受不使用拆分而是通过多次匹配,则可以使用
(?<=\ \|\|\ |^)([^\"]+?(?:\"[^\"]*\")?)+?(?=\ \|\|\ |$) 说明:

  1. 后瞻:“||”还是行首?
  2. 一些非引用文字,尽可能少
  3. 可选地,引用括号的非引号
  4. 2-3。至少重复一次
  5. 预见:“||”或行尾?
  6. 匹配将恰好是“||”与引用||分开的结果忽略。

答案 3 :(得分:0)

拆分双管道,但只有那些后跟偶数引号的那些:

String[] parts = str.split("\\|\\|(?=(([^\"]*\"){2})*[^\"]*$");

答案 4 :(得分:0)

使用这个简短的正则表达式 \|\|(?!\([^\)]+\))它可能有用。

Live demo