为什么String.split()在这里返回额外的元素?

时间:2013-05-13 06:23:49

标签: java regex

我正在尝试使用regexp拆分字符串,该字符串返回数组中的额外元素。请帮忙。以下是该计划:

public class Test {
    public static void main(String[] arg){
    String str1 = "{abc}{def}";
    String delim = "[{}]+";

    String[] tokens = str1.split(delim);

    for (int i = 0; i < tokens.length; i++) {
        System.out.println("token value: "+ tokens[i]);
        }        
    }    
}

输出:

token value: 
token value: abc
token value: def

为什么第一个令牌为空字符串?如何解决这个问题?

3 个答案:

答案 0 :(得分:5)

你有一个空的初始元素的原因是目标字符串以分隔符开头。就像在",1,2"上拆分,会导致三个条目,第一个为空白,您得到相同的结果。 (你不会在 end 上留下空白,因为String#split会明确删除它们,除非你给它一个负的第二个参数。)

如果您知道字符串将以分隔符开头并且它是一个字符,请将其删除:

String[] tokens = str1.substring(1).split(delim);

编辑:或者对于一般情况,see Bohemian's answer他删除第一个匹配的delim,无论长度如何。

否则,你可以循环:

import java.util.regex.*;

public class SplitTest {
    public static void main(String[] arg){
        String str1 = "{abc}{def}";

        Matcher m = Pattern.compile("\\{([^}]+)\\}").matcher(str1);
        while (m.find()) {
            System.out.println("token value: " + m.group(1));
        }
    }
}

以下是该模式字符串的细分:

  • 开头的\\{与文字{
  • 相匹配
  • (和相应的)稍后会创建捕获组
  • 在捕获组中,[^}]+表示“不是}
  • 的任何字符中的一个或多个
  • 跟踪\\}匹配文字}

然后我们循环遍历字符串中的匹配项,获取捕获组的值

答案 1 :(得分:2)

问题是它在第一个char之前分裂。要修复,只需在拆分前剥去前导分隔符:

String[] tokens = str1.replaceAll("^" + delim, "").split(delim);

如果你只需要遍历各个部分(而不是保留数组,你可以将方法的整个工作部分分成两行:

for (String token : str1.replaceAll("^" + delim, "").split(delim))
    System.out.println("token value: " + token);

或者只是一行(只有一个分号!)如果你不介意宽线:

for (String token : str1.replaceAll("^" + delim, "").split(delim)) System.out.println("token value: " + token);

答案 2 :(得分:0)

如果您确定输入的语言/格式,那么您可以这样做:

public class Test {
    public static void main(String[] arg){
    String str1 = "{abc}{def}";

    String[] tokens = str1.split("}");

    for (int i = 0; i < tokens.length; i++) {
        String realToken = tokens[i].substring(1); // This strips off the leading "{"
        System.out.println("token value: " + realToken);
    }
}

为什么原始示例中的前导空字符串标记?这是因为字符串以分隔符开头。想想看:如果它不会返回一个空字符串作为你的情况下的第一个元素,那么当字符串以分隔符开头而不是分隔符时,你如何区分这些情况呢?