答案,请看下面 - 士气:从不.split()单独打电话; 如果你想要理智的行为,总是给它一个-1的长度参数.但不是0!
在对javadoc的Pattern.split()状态如下:
此方法返回的数组包含输入序列的每个子字符串,该子字符串由与此模式匹配的另一个子序列终止,或者由输入序列的末尾终止.
见证这段代码:
private static final Pattern UNDERSCORE = Pattern.compile("_");
public static void main(final String... args)
{
System.out.println(UNDERSCORE.split("_").length);
}
Run Code Online (Sandbox Code Playgroud)
现在,引用javadoc,数组应该包含输入的子字符串(引用):
UNDERSCORE显然匹配);然而,上面的代码打印出来0.为什么?这是一个已知的错误?(imnsho是的,见下文)还有哪些.split()不遵守合同的情况?(再见下文)
答案(右下方的解释性文字)
使用a时Pattern,单参数.split()方法相当于使用参数调用双参数方法0.
这就是错误所在.如果参数为0,则从结果中删除从数组末尾"向下"到第一个非空元素的所有空字符串.
如果在阅读本文之前,你不知道脑死亡设计的决定是什么,现在你知道了.这是默认行为更加危险.
解决方案是始终使用方法的完整形式.split()并给它一个负长度参数.这里,选择-1.在这种情况下,.split()表现得很明智:
private static final Pattern UNDERSCORE = Pattern.compile("_");
public static void main(final String... args)
{
System.out.println(UNDERSCORE.split("_").length);
System.out.println(UNDERSCORE.split("__").length);
System.out.println(UNDERSCORE.split("_x_").length);
System.out.println(UNDERSCORE.split("_", -1).length);
System.out.println(UNDERSCORE.split("__", -1).length);
System.out.println(UNDERSCORE.split("_x_", -1).length);
}
Run Code Online (Sandbox Code Playgroud)
输出:
0 # BUG!
0 # BUG!
2 # BUG!
2 # OK
3 # OK
3 # OK
Run Code Online (Sandbox Code Playgroud)
从相同的文档:
该
limit参数控制应用模式的次数,因此会影响结果数组的长度.如果n [限制]为零,则模式将被应用尽可能多的次数,数组可以具有任何长度,并且将丢弃尾随的空字符串.
确定限制的默认值0:
Run Code Online (Sandbox Code Playgroud)public String[] split(CharSequence input)...
此方法的工作方式就像通过调用给定输入序列和limit参数为零的双参数split方法一样.
因此,丢弃空字符串.
如果你想使用它UNDERSCORE.split("_", -1),或任何其他负整数.
编辑:清除混淆:根据你的推理,返回的数组是负数限制,是这样的:
[ "" , "" ]
Run Code Online (Sandbox Code Playgroud)
如果使用非正限制,则会删除所有尾随空字符串.最后一个元素是一个空字符串,因此将其删除.然后,你有:
[ "" ]
Run Code Online (Sandbox Code Playgroud)
最后一个元素也是一个空字符串,因此它也被删除.
换句话说,尾随不是指在初始字符串中尾随,而是在最终数组中尾随.
也可以看看: