正则表达式找到不在“(和)”内的逗号

时间:2010-08-07 00:10:27

标签: java regex

我需要一些帮助来模拟这个正则表达式。我认为用一个例子会更容易。我需要一个与逗号匹配的正则表达式,但前提是它不在此结构中:"( )",如下所示:

,a,b,c,d,"("x","y",z)",e,f,g,

然后前五个和后四个逗号应与表达式匹配,xyz( )部分之间的两个逗号不应该匹配。

我尝试了很多组合,但正则表达式对我来说仍然有点模糊。

我希望它与Java中的split方法一起使用。这个例子很简短,但它可以更长,并且在“(和)”之间有不止一个部分。 split方法接收一个表达式,如果某些文本(在本例中为逗号)与表达式匹配,则它将成为分隔符。

所以,想做这样的事情:

String keys[] = row.split(expr);
System.out.println(keys[0]); // print a
System.out.println(keys[1]); // print b
System.out.println(keys[2]); // print c
System.out.println(keys[3]); // print d
System.out.println(keys[4]); // print "("x","y",z)"
System.out.println(keys[5]); // print e
System.out.println(keys[6]); // print f
System.out.println(keys[7]); // print g

谢谢!

6 个答案:

答案 0 :(得分:14)

您可以使用否定前瞻来执行此操作。这是一个稍微简化的问题来说明这个想法:

String text = "a;b;c;d;<x;y;z>;e;f;g;<p;q;r;s>;h;i;j";

String[] parts = text.split(";(?![^<>]*>)");

System.out.println(java.util.Arrays.toString(parts));
//  _  _  _  _  _______  _  _  _  _________  _  _  _
// [a, b, c, d, <x;y;z>, e, f, g, <p;q;r;s>, h, i, j]

请注意,除了,,分隔符现在是;,而不是"("),括号只是<和{{ 1}},但这个想法仍然有用。


关于模式

>character class。像[…]这样的东西匹配任何一个小写元音。 [aeiou]否定的字符类。 [^…]除了小写元音之外的任何内容匹配。

[^aeiou]重复说明符可用于匹配前一个模式的“零次或多次”。

*是一个负向前瞻;它可用于断言某个模式不会匹配,向前看(即向右)当前位置。

模式(?!…)匹配除括号外的所有内容的序列(可能为空),最后是一个关闭类型的paranthesis。

将上述所有内容放在一起,我们得到[^<>]*>,它与;(?![^<>]*>)匹配,但前提是我们看不到右括号作为右边的第一个括号,因为见证了这种现象只会意味着;在括号内“。”

这项技术经过一些修改后,可以适应原始问题。请记住在必要时转义正则表达式元字符;(,当然{Java}字符串中的)"必须通过前缀{{1}来转义}}

你也可以使\占有欲试图改善表现,即\

参考

答案 1 :(得分:6)

试试这个:

(?![^(]*\)),

在我的测试中,它对我有用,抓住了不在括号内的所有逗号。

编辑:Gopi指出需要逃避Java中的斜杠:

(?![^(]*\\)),

编辑:Alan Moore指出了一些不必要的复杂性。固定的。

答案 2 :(得分:2)

如果parens配对正确且无法嵌套,您可以先在parens中拆分文本,然后处理这些块。

List<String> result = new ArrayList<String>();
String[] chunks = text.split("[()]");
for (int i = 0; i < chunks.length; i++) {
  if ((i % 2) == 0) {
    String[] atoms = chunks[i].split(",");
    for (int j = 0; j < atoms.length; j++)
      result.add(atoms[j]);
  }
  else
    result.add(chunks[i]);
}

答案 3 :(得分:1)

那么,

经过一些测试,我刚刚找到了一个答案,它正在做我现在所需要的。此时,“(...)”块内的所有itens都在“”里面,如:“(”a“,”b“,”c“)”,然后,正则表达式((?<!\"),)|(,(?!\"))非常适合我想要的东西!

但即使内部条款中没有“”,我仍然在找一个能找到逗号的人。

感谢帮助人员。

答案 4 :(得分:1)

这应该做你想要的:

(".*")|([a-z])

我没有在java中检查但是如果你使用http://www.fileformat.info/tool/regex.htm进行测试 组$ 1和$ 2包含正确的值,因此它们匹配,你应该得到你想要的。 如果你在逗号之间有比a-z更复杂的值,那么这将会变得更加棘手。

如果我正确理解了拆分,请不要使用它,只需用后引用$ 0填充数组,$ 0保存您要查找的值。 也许匹配函数是一种更好的方法,使用这些值更好,因为你会得到这个非常简单的regExp。到目前为止我看到的其他解决方案都非常好,毫无疑问,但它们真的很复杂,在2周内你还不知道rexExp究竟做了什么。 通过反转问题本身,问题变得更加简单。

答案 5 :(得分:0)

我有同样的问题。我选择Adam Schmideg回答并改进它。

我必须处理这3个字符串,例如:

  1. France (Grenoble, Lyon), Germany (Berlin, Munich)
  2. Italy, Suede, Belgium, Portugal
  3. France, Italy (Torino), Spain (Bercelona, Madrid), Austria
  4. 想法是:

    1. France (Grenoble, Lyon)Germany (Berlin, Munich)
    2. ItalySuedeBelgiumPortugal
    3. FranceItaly (Torino)Spain (Bercelona, Madrid)Austria
    4. 我选择不使用正则表达式,因为我是我正在做的100%,并且在任何情况下都可以使用。

      String[] chunks = input.split("[()]");
      for (int i = 0; i < chunks.length; i++) {
          if ((i % 2) != 0) {
              chunks[i] = "("+chunks[i].replaceAll(",", ";")+")";
          }
      }
      StringBuffer buffer = new StringBuffer();
      for (int i = 0; i < chunks.length; i++) {
          buffer.append(chunks[i]);
      }
      String s = buffer.toString();
      String[] output = s.split(",");