如何拆分字符串,只保留某些分隔符?

时间:2016-08-20 21:54:17

标签: java regex split regex-lookarounds

我有一个类似于How to split a string, but also keep the delimiters?的问题。我如何使用正则表达式拆分字符串,保留某些类型的分隔符,而不是其他类型的分隔符?具体来说,我想保留非空白分隔符,但不保留空白分隔符。

使这具体化:

"a;b c"        | ["a", ";", "b", "c"]
"a; ; bb c ;d" | ["a", ";", ";", "bb", "c", ";", "d"]

这可以用正则表达式干净利落地完成,如果是这样的话?

现在我正在通过拆分要保留的角色来解决这个问题,然后再对另一个角色进行处理。如果正则表达式不能这样做,或者不能干净利落,我可以坚持这种方法:

Arrays.stream(input.split("((?<=;)|(?=;))"))
        .flatMap(s -> Arrays.stream(s.split("\\s+")))
        .filter(s -> !s.isEmpty())
        .toArray(String[]::new); // In practice, I would generally use .collect(Collectors.toList()) instead

6 个答案:

答案 0 :(得分:3)

我建议捕捉你想要的东西,而不是使用这个简单的模式分裂

1) Kyle
2) Cartman
3) Stan
4) Quit
Select character: Kyle
name=
Select character: Stan
name=
Select character: 

Demo

答案 1 :(得分:2)

你可以这样做:

System.out.println(String.join("-", "a; ; b c ;d".split("(?!\\G) *(?=;)|(?<=;) *| +")));

细节:

(?!\\G)  # not contiguous to a previous match and not at the start of the string
[ ]*     # optional spaces
(?=;)    # followed by a ;
|    # OR
(?<=;)   # preceded by a ;
[ ]*     # optional spaces
|    # OR
[ ]+     # several spaces 

随意将文字空间更改为\\s。要避免空项(当字符串以空格开头时在结果数组的开头),您需要先修剪字符串。

显然,没有分裂的约束,@ alphabravo方式是最简单的。

答案 2 :(得分:2)

我找到了一个有效的正则表达式:

(\\s+)|((?<=;)(?=\\S)|(?<=\\S)(?=;))
public static void main(String argss[]){
    System.out.println(Arrays.toString("a; ; b c ;d"
        .split("(\\s+)|((?<=;)(?=\\S)|(?<=\\S)(?=;))")));
}

将打印出来:

[a, ;, ;, b, c, ;, d]

答案 3 :(得分:1)

您希望在空格上或在字母和非字母之间拆分:

str.split("\\s+|(?<=\\w)(?=\\W)|(?<=\\W)(?=\\w)");

答案 4 :(得分:1)

意识到Java不支持将捕获的拆分字符添加到
拆分数组元素,以为我会尝试一个没有那个的拆分解决方案 能力。

基本上只有4个涉及空格和冒号的排列 最后,只有空白。

这是正则表达式。

原始:\s+(?=;)|(?<=;)\s+|(?<!\s)(?=;)|(?<=;)(?!\s)|\s+

弦乐:"\\s+(?=;)|(?<=;)\\s+|(?<!\\s)(?=;)|(?<=;)(?!\\s)|\\s+"

解释了扩展的正则表达式 祝好运!

    \s+                  # Required, suck up wsp before ;
    (?= ; )              # ;

 |                     # or,

    (?<= ; )             # ;
    \s+                  # Required, suck up wsp after ;

 |                     # or,

    (?<! \s )            # No wsp before ;
    (?= ; )              # ;

 |                     # or,

    (?<= ; )             # ;
    (?! \s )             # No wsp after ;

 |                     # or,

    \s+                  # Required wsp

修改

要停止在BOS上的空格分割,请使用此正则表达式。

原始:\s+(?=;)|(?<=;)\s+|(?<!\s)(?=;)|(?<=;)(?!\s)|(?<!^)(?<!\s)\s+

弦乐:"\\s+(?=;)|(?<=;)\\s+|(?<!\\s)(?=;)|(?<=;)(?!\\s)|(?<!^)(?<!\\s)\\s+"

解释:

    \s+                  # Required, suck up wsp before ;
    (?= ; )              # ;

 |                     # or,

    (?<= ; )             # ;
    \s+                  # Required, suck up wsp after ;

 |                     # or,

    (?<! \s )            # No wsp before ;
    (?= ; )              # ;

 |                     # or,

    (?<= ; )             # ;
    (?! \s )             # No wsp after ;

 |                     # or,

    (?<! ^ )             # No split of wsp at BOS   
    (?<! \s )
    \s+                  # Required wsp

答案 5 :(得分:0)

借用@CasimiretHippolyte \\s+|(?!\\G)() 技巧,你可能想分开

(?m)(?<!^|\\s)(\\s+|)(?!$)

注意:未指定分隔符。

更新

基于避免在第一个空格上拆分:

{{1}}