如何使用条件拆分字符串

时间:2014-08-13 18:02:37

标签: java regex string split

分割字符串时,如何确定如果分隔符位于两个字符之间,那么它不会被视为

// 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"

2 个答案:

答案 0 :(得分:4)

答案结尾处的首选方法

您似乎正在寻找look-around机制。

例如,如果您希望拆分之前没有foo的空格而且之后没有bar,那么您的代码可能看起来像

split("(?<!foo)\\s(?!bar)")

更新(假设不能存在任何嵌套[...]并且格式正确,例如[所有]都已关闭,) :

你的情况似乎有点复杂。您可以做的是接受[ if

  • 之后没有][
  • 或者如果在此逗号后面第一个打开括号],则此逗号与其自身之间没有右括号[ , ] [ ^ ^ ^ - first `[` after tested comma | +---- one `]` between tested comma and first `[` after it +------ tested comma ,否则表示逗号位于区域内

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

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

[foo,bar]

此正则表达式基于您不想接受的逗号位于[内的想法。但是如何确定我们在这个区块内部(或外部)?

  1. 如果字符在里面,那么之后就不会有]个字符,直到我们找到[(下一个]可以在找到[a,b],[c,d]之后显示,例如ab[之间的逗号之前没有],直到找到[..],但是在它之后可能会有一些新的区域[ [...]
  2. 如果字符在]区域之外,那么在它只能显示非[...]字符后,接下来我们会找到,区域的开头,或者我们将读取字符串的结尾。
  3. 第二种情况是你感兴趣的。所以我们需要创建一个正则表达式,它接受]之后只有非[...](它不在[内)直到它找到$或读取字符串的结尾(由,表示)

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

    • (?=...)逗号
    • [^\\]]*(\\[|$)之后有
    • [^\\]]*
      • ]零个或多个非]个字符((\\[|$)需要作为元字符进行转义)
      • [其中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
    

    输出:

    {{1}}

答案 1 :(得分:1)

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

(?<!\[\w),(?!\w\])

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

  • (?<!\[\w) =匹配不能 [x x 任何字符 < /强>
  • , =匹配应为逗号
  • (?!\w\]) =匹配不能之前 x] x 任何字符 < /强>

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

String[] split = text.split("(?<!\\[\\w),(?!\\w\\])");

<强>输出

a
b
[c,d]
e