如何使用条件拆分字符串

拆分字符串时,如何确定如果分隔符位于两个字符之间,那么它将不会被考虑

// Input String string = "a,b,[c,d],e"; String[] split = string.split(","); // Output split[0] // "a" split[1] // "b" split[2] // "[c" split[3] // "d]" split[4] // "e" // Required split[0] // "a" split[1] // "b" split[2] // "[c,d]" split[3] // "e" 

答案结束时的首选方法

看来你正在寻找环视机制。

例如,如果你想拆分之前没有foo空格而且之后没有任何bar你的代码可能看起来像

 split("(? 

更新 (假设没有任何嵌套的[...]并且它们格式正确,例如所有[关闭] ):

你的情况似乎有点复杂。 你能做的就是接受,如果

  • 它之后没有任何[]
  • 或者如果这个逗号和它本身之间的第一个打开括号[在这个逗号之后,没有右括号] ,否则它将意味着逗号位于区域之内

     [ , ] [ ^ ^ ^ - first `[` after tested comma | +---- one `]` between tested comma and first `[` after it +------ tested comma 

所以你的代码看起来像
(这是原始版本,但下面是简化版)

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

这个正则表达式是基于你不想接受的逗号在[foo,bar]内的想法。 但是如何确定我们在这样的区域内(或外部)呢?

  1. 如果字符在里面,则不会有[后面的字符,直到我们找到] (下一个[可以在找到之后出现] ,如果ab之间a [a,b],[c,d]逗号没有[直到它发现] ,但在它之后可能会有一些新的区域[..]
  2. 如果字符在[...]区域之外,那么接下来它只能出现非字符,直到我们找到[...]区域的开头,或者我们将读取字符串的结尾。

第二种情况是你感兴趣的那种。所以我们需要创建正在接受的正则表达式,它只有非后面的(它不在[...] ),直到它找到[或读取字符串的结尾(由...表示) $

这样的正则表达式可以写成

  • ,逗号
  • (?=...)之后有
  • [^\\]]*(\\[|$)
    • [^\\]]*零个或多个非]字符( ]需要作为元字符进行转义)
    • (\\[|$)[它也需要在正则表达式中转义]或者在它之后的字符串结尾

小简化拆分版

 string.split(",(?![^\\[]*\\])"); 

这意味着:在逗号上拆分,在它之后没有(由(?!...)表示)未闭合] (未闭合]没有[在被测试的逗号和本身之间可以写为[^\\[]*\\]


首选方法

要避免这种复杂的正则表达式,请不要使用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()); 

输出:

 a b [c,d] e 

一个简单的正则表达式将满足您的需求:

 (? 

此正则表达式表示以下内容:

  • (? =匹配不能 [x ,其中x任何字符
  • , =匹配应该是逗号
  • (?!\w\]) =匹配不能 x] 之前 ,其中x任何字符

您可以按如下方式使用它:

 String[] split = text.split("(? 

输出

 a b [c,d] e