使用模式匹配在多字符分隔符上拆分一条线

时间:2014-09-24 22:13:34

标签: java regex

我正在运行以下简单程序:

public class TestClass {
    public static void main(final String[] args) {
        String valid = "abc|~abc|~abc|~abc|~abc|~|~|~|~|~|~|~abc";
        String invalid = "xyz|~xyz|~xyz|~xyz|~xyz|~|~|~|~|~|~|~";
        String delimiter = "|~";
        Pattern pattern = Pattern.compile(Pattern.quote(delimiter));
        String[] tokensValid = pattern.split(valid);
        String[] tokensInvalid = pattern.split(invalid);
        System.out.println("Valid: " + tokensValid.length);
        System.out.println("InValid: " + tokensInvalid.length);
    }
}

输出结果为:

Valid: 12
InValid: 5

但我觉得输出应该是:

Valid: 12
InValid: 12

它是如何运作的?

2 个答案:

答案 0 :(得分:3)

one-arg overload of String.split将丢弃所有空的尾随空标记。

  

此方法的工作方式就像调用带有给定表达式和limit参数为零的双参数split方法一样。因此,尾随空字符串不包含在结果数组中。

你有7个。这就是你为“InValid”案件获得5的原因。

要获得12,您必须使用two-arg overload of String.split,其中包含一个负限制(或至少为12的限制),这不会丢弃尾随的空标记。

  

limit参数控制模式的应用次数,因此会影响结果数组的长度。如果限制n大于零,那么模式将最多应用n - 1次,数组的长度将不大于n,并且数组的最后一个条目将包含除最后一个匹配分隔符之外的所有输入。如果n是非正数,那么模式将被应用尽可能多的次数,并且数组可以具有任何长度。如果n为零,那么模式将被应用尽可能多次,数组可以具有任何长度,并且尾随空字符串将被丢弃。

答案 1 :(得分:1)

来自split method documentation(强调我的)

  

此方法的作用就像通过调用给定输入序列和limit参数为零的双参数split方法一样。 因此,结尾数组中不包含尾随空字符串

换句话说,在"xyz|~xyz|~xyz|~xyz|~xyz|~|~|~|~|~|~|~"上分割|~将在开始时生成数组

["xyz","xyz","xyz","xyz","xyz","","","","","","",""]

但是因为调用的内部split(CharSequence input, int limit)方法中的limit参数设置为0删除了空字符串,这意味着您得到的结果数组是

["xyz","xyz","xyz","xyz","xyz"]

长度为5。

根据这些方法的文档,如果您想避免删除尾随空字符串,可以使用此方法使用负limit

String[] tokensInvalid = pattern.split(invalid, -1);
//                                              ^^^