Java 正则表达式元字符在拆分时返回额外的 space

Java Regex Metacharacters returning extra space while spliting

我想使用正则表达式而不是 StringTokenizer 来拆分字符串。我正在使用 String.split(regex); 正则表达式包含元字符,当我使用 \[ 时,它在返回数组中返回额外的 space 。

import java.util.Scanner;
public class Solution{
    public static void main(String[] args) {
        Scanner i= new Scanner(System.in);
        String s= i.nextLine();
        String[] st=s.split("[!\[,?\._'@\+\]\s\\]+");
        System.out.println(st.length);
        for(String z:st)
            System.out.println(z);
        }
}

当我输入时 [a\m] 它returns数组长度为3并且

 a m  

Space前面也有一个。 任何人都可以解释为什么会发生这种情况以及我该如何纠正它。我不希望结果数组中有额外的 space。

由于[在字符串的开头,当split去掉[时,第一次拆分后出现了两个元素:字符串的开头,以及字符串的其余部分。 String#split 不只 return 尾随 空元素(因为它默认使用 limit=0 执行)。

从开头删除您拆分的字符(使用 .replaceAll("^[!\[,?._'@+\]\s\\]+",注意模式开头的 ^)。这是您可以利用的示例代码:

String[] st="[a\m]".replaceAll("^[!\[,?._'@+\]\s\\]+", "")
                 .split("[!\[,?._'@+\]\s\\]+");
System.out.println(st.length);
for(String z:st) {
    System.out.println(z);
}

demo

作为 , you may do the same without having to specify the pattern twice, by dealing with the java.util.regex 包的补充。删除此冗余可以避免潜在的错误,也可以更有效,因为模式不需要解析两次:

Pattern p = Pattern.compile("[!\[,?\._'@\+\]\s\\]+");
Matcher m = p.matcher(s);
if(m.lookingAt()) s=m.replaceFirst("");
String[] st = p.split(s);
for(String z:st)
    System.out.println(z);

为了能够使用相同的模式,即不必使用锚 ^ 来删除前导分隔符,我们首先通过 lookingAt() 检查模式是否真的匹配删除第一次出现之前的文本。然后,我们继续 split 操作,但重新使用已经准备好的 Pattern.


关于您在评论中提到的问题,split 操作将始终 return 至少一个元素,即输入字符串,当没有匹配项时,即使字符串为空。如果您希望有一个空数组,那么唯一的解决方案是显式替换结果:

if(st.length==1 && s.equals[0]) st=new String[0];

或者,如果你只想特殊处理一个空字符串,你可以事先检查一下:

if(s.isEmpty()) st=new String[0];
else {
  // the code as shown above
}