Preferred approach at the end of the answer
看来您正在寻找环视四周 http://www.regular-expressions.info/lookaround.html机制。
例如,如果你想在没有空格的空白处进行分割foo
之前和没有bar
之后你的代码看起来像
split("(?<!foo)\\s(?!bar)")
Update(假设不能有任何嵌套[...]
它们的格式很好,例如所有[
关闭于]
):
你的情况似乎更复杂一些。你能做的就是接受,
if
- 它没有任何
[
or ]
之后,
-
或者如果第一个左括号[
该逗号之后没有右括号]
在此逗号和其自身之间,否则意味着逗号在区域内,例如
[ , ] [
^ ^ ^ - first `[` after tested comma
| +---- one `]` between tested comma and first `[` after it
+------ tested comma
So your code can look like
(this is original version, but below is little simplified one)
split(",(?=[^\\]]*(\\[|$))")
这个正则表达式基于这样的想法:你不想接受的逗号在里面[foo,bar]
。但是如何确定我们在这个块的内部(或外部)呢?
- 如果字符在里面那么就不会有
[
其后的字符,直到我们找到]
(next [
找到后即可出现]
就像万一[a,b],[c,d]
之间有逗号a
and b
has no [
直到找到]
,但是可能会有一些新的区域[..]
在它之后当然开始于[
)
- 如果角色在外面
[...]
区域然后下一个之后它只能出现非]
字符,直到我们找到开始[...]
区域,否则我们将读取字符串末尾。
第二种情况是您感兴趣的情况。因此我们需要创建将接受的正则表达式,
其中只有非]
在它之后(它不在里面[...]
)直到找到[
或读取字符串末尾(由$
)
这样的正则表达式可以写成
-
,
comma
-
(?=...)
其后有
-
[^\\]]*(\\[|$)
-
[^\\]]*
零个或多个非]
人物 (]
需要作为元字符转义)
-
(\\[|$)
其中有[
(它也需要在正则表达式中转义)或后面的字符串结尾
小简化分割版
string.split(",(?![^\\[]*\\])");
这意味着:用逗号分割,
之后它没有(表示为(?!...)
) 未关闭]
(未关闭]
has no [
在测试的逗号和它本身之间,可以写成[^\\[]*\\]
)
首选方法
为了避免如此复杂的正则表达式,不要使用split
但是 Pattern 和 Matcher 类,它们将搜索类似的区域[...]
或非逗号词。
String string = "a,b,[c,d],e";
Pattern p = Pattern.compile("\\[.*?\\]|[^,]+");
Matcher m = p.matcher(string);
while (m.find())
System.out.println(m.group());
Output:
a
b
[c,d]
e