Java string.split(“\\S”)是如何工作的
我在做一个来自Ganesh和Sharma的《甲骨文认证专业人员》、《java》、《se》、《程序员考试》、《1z0-804》和《1z0-805》一书的问题 一个问题是:Java string.split(“\\S”)是如何工作的,java,regex,ocpjp,Java,Regex,Ocpjp,我在做一个来自Ganesh和Sharma的《甲骨文认证专业人员》、《java》、《se》、《程序员考试》、《1z0-804》和《1z0-805》一书的问题 一个问题是: 考虑以下程序并预测输出: class Test { public static void main(String args[]) { String test = "I am preparing for OCPJP"; String[] tokens = test.split("\\S");
class Test {
public static void main(String args[]) {
String test = "I am preparing for OCPJP";
String[] tokens = test.split("\\S");
System.out.println(tokens.length);
}
}
a) 0
b) 五,
c) 十二,
d) 十六,for (String str: tokens){
System.out.println("<" + str + ">");
}
for(字符串str:tokens){
System.out.println(“”);
}
我得到了以下输出
16
< >
< >
< >
< >
所以有很多空字符串标记。
我就是不明白
我会这样想,如果分隔符是非空格字符,那么在上面的文本中,所有字母字符都作为分隔符,所以如果我们匹配,可能应该有21个标记
也会导致空字符串的标记。我只是不明白Java的正则表达式引擎是如何解决这个问题的。有没有任何正则表达式大师可以为我解释这段代码?首先从
\s
(小写)开始,这是一个用于空白的正则表达式字符类,即空格“tabs”\t、“新行字符”\n“和“\r”、垂直制表符“\v”和一组其他字符
\S
(大写)与此相反,因此表示任何非空白字符
因此,当您使用\S
拆分此字符串“我正在准备OCPJP
”时,实际上就是在每个字母处拆分字符串。令牌数组长度为16的原因
至于为什么这些是空的
考虑以下字符串:Hello,World
,如果我们使用,
拆分该字符串,我们将得到一个长度为2的字符串数组,其内容如下:Hello
和World
。请注意,,
不在这两个字符串中,它已被擦除
同样的事情发生在我正在准备OCPJP
字符串上,它已经被拆分,并且正则表达式匹配的点不在任何返回值中。由于该字符串中的大多数字母后面都跟有另一个字母,因此最终会出现一堆长度为零的字符串,只保留空白字符。复制自API:(粗体是我的)
围绕给定正则表达式的匹配项拆分此字符串。
此方法的工作方式类似于通过调用具有
给定的表达式和零的极限参数尾随空
因此,结果数组中不包括字符串。
例如,字符串“boo:and:foo”产生以下结果
用这些表达:
Regex Result
: { "boo", "and", "foo" }
o { "b", "", ":and:f" }
检查第二个示例,其中最后2个“o”刚刚被删除:您的问题的答案是
“OCPJP”
子字符串被视为一组分隔符,非空字符串不遵循这些分隔符,因此该部分被修剪。结果是16而不是21的原因是:
因此,结果中不包括尾随的空字符串
数组
这意味着,例如,如果你说
"/abc//def/ghi///".split("/")
结果将有五个要素。第一个将是”
,因为它不是尾随的空字符串;其他将是“abc”
,“
,“def”
,和“ghi”
。但是剩余的空字符串将从数组中删除
在这种情况下:
"I am preparing for OCPJP".split("\\S")
是一样的。由于非空格字符是分隔符,因此每个字母都是分隔符,但OCPJP字母基本上不计算在内,因为这些分隔符会导致随后丢弃的空字符串。因此,由于我正在为“”准备的“”中有15个字母,它们被视为分隔16个子字符串(第一个是
”
,最后一个是”
)。我试过你的例子,如果你用\\S替换\\S,会不会是打字错误?@mreiter这是为了认证考试,为什么他们会把这样一个棘手的案子扔进去呢?事实上,他们将正确答案(16)作为选择之一,这使得这不太可能是无意的。如果21是其中一个选择,我可能会弄错。嗨,不,这是\\S的反面。问题的关键是:为什么是16岁而不是21岁?为什么“OCPJP”不被视为一堆分离器?共有21个字母,但最后一个字母被忽略了……说得好,遗漏了问题的这一部分!感谢您指出这一点,并在回答中突出显示文档。感谢Pablo,如果您忽略最后一个空格后的空字符串,这是有意义的。这就解释了这个数字。16而不是21。这是一个稍有不同的观点,但假设您有一个逗号分隔的文件,文件末尾的值为空,如果没有填写,则表示它来自excel电子表格,用户没有输入值。这是否意味着String.split会将它们扔掉。如果您希望处理数据,可能会导致严重的错误。大声思考:-)。是的,这就是在分割CSV行时必须检查数组长度的原因。如果你把它和CSV格式没有任何标准的事实结合起来……在这种情况下,你可能想考虑<代码>分裂(“,”,-1)< /代码>。
"I am preparing for OCPJP".split("\\S")