我需要一些帮助来模拟这个正则表达式。我认为用一个例子会更容易。我需要一个与逗号匹配的正则表达式,但前提是它不在此结构中:"( )"
,如下所示:
,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
谢谢!
答案 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个字符串,例如:
France (Grenoble, Lyon), Germany (Berlin, Munich)
Italy, Suede, Belgium, Portugal
France, Italy (Torino), Spain (Bercelona, Madrid), Austria
想法是:
France (Grenoble, Lyon)
或Germany (Berlin, Munich)
Italy
,Suede
,Belgium
,Portugal
France
,Italy (Torino)
,Spain (Bercelona, Madrid)
,Austria
我选择不使用正则表达式,因为我是我正在做的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(",");