Java .split 方法匹配空字符串奇怪的行为
Java .split method matches empty string weird behaviour
我想从字符序列(即:字母和数字)中获取数字列表。所以我写了这段代码:
class A {
public static void main(String[] args) {
String msg = "aa811b22";
String[] numbers = msg.split("\D+");
for (int i = 0; i < numbers.length; i++) {
System.out.println(">" + numbers[i] + "<");
}
}
}
超乎想象地运行...:[=23=]
$ java A
><
>811<
>22<
好吧,所以它以某种方式匹配空字符串...我向自己解释说 ""
(空字符串)实际上匹配 NON DIGIT MATCHER
的正则表达式,所以 \D+
。没有什么不是数字......对吧? (然而...为什么它只返回1个空字符串?任何字符串中都有无限(∞)个空字符串)
为了确保自己,我尝试从上面给出的字符串中提取单词:
class A {
public static void main(String[] args) {
String msg = "aa811b22";
String[] words = msg.split("\d+");
for (int i = 0; i < words.length; i++) {
System.out.println(">" + words[i] + "<");
}
}
}
这实际上打印了我所期望的(没有返回空字符串):
$ run A
>aa<
>b<
但是...我做了几个完全让我困惑的测试:
System.out.println("a".split("\D+").length);
#=> 0 (WHY NOT 1? Empty string shouldn't be here?!)
System.out.println("a1".split("\D+").length);
#=> 2 (So now it splits to empty string and 1)
System.out.println("1a".split("\D+").length);
#=> 1 (now it returns expected "a" string)
所以我的问题是:
- 为什么要用我给出的例子拆分 returns 空字符串?
- 为什么
"a".split("\D+").length
returns 0 ?
- 为什么
"a1".split("\D+").length
是 2(但没有一个)
"1a".split("\D+").length)
与 "a1".split("\D+").length)
有何不同
在分裂的情况下?
不匹配空字符串。相反,它匹配字符串开头的 "aa"
作为分隔符。第一个元素为空,因为在第一个分隔符之前只有一个空字符串。相反,对于尾随定界符,没有返回空字符串,如 documentation for split():
中所述
This method works as if by invoking the two-argument split method with
the given expression and a limit argument of zero. Trailing empty
strings are therefore not included in the resulting array.
- 为什么要用我给出的例子拆分 return 的空字符串?
'a'
不是数字,所以 aa
是分隔符。分隔符的两边都有 return 的元素,空字符串在 a
的左边。如果分隔符是 ","
,那么在字符串 ",a,b"
之外,您会期望有 3 个元素 -- ""
、"a"
和 "b"
。在这里,aa
是分隔符,就像我示例中的 ,
。
- 为什么
"a".split("\D+").length
returns 0 ?
'a'
不是数字,所以它是一个分隔符。分隔符的存在意味着在 a
的两边有两个从原始 String
中拆分出来的子串,均为空字符串。但是,no-arg split
method 会丢弃尾随的空字符串。它们都是空的,所以它们都被丢弃了,length
是0
。
- 为什么
"a1".split("\D+").length
是 2(而不是一个)
仅丢弃尾随的空字符串,因此元素为 ""
和 "1"
。
- 在拆分的情况下,
"1a".split("\D+").length
与 "a1".split("\D+").length
有何不同?
"1a"
将丢弃一个尾随空字符串,但 "a1"
不会丢弃尾随空字符串(它是前导的)。
我想从字符序列(即:字母和数字)中获取数字列表。所以我写了这段代码:
class A {
public static void main(String[] args) {
String msg = "aa811b22";
String[] numbers = msg.split("\D+");
for (int i = 0; i < numbers.length; i++) {
System.out.println(">" + numbers[i] + "<");
}
}
}
超乎想象地运行...:[=23=]
$ java A
><
>811<
>22<
好吧,所以它以某种方式匹配空字符串...我向自己解释说 ""
(空字符串)实际上匹配 NON DIGIT MATCHER
的正则表达式,所以 \D+
。没有什么不是数字......对吧? (然而...为什么它只返回1个空字符串?任何字符串中都有无限(∞)个空字符串)
为了确保自己,我尝试从上面给出的字符串中提取单词:
class A {
public static void main(String[] args) {
String msg = "aa811b22";
String[] words = msg.split("\d+");
for (int i = 0; i < words.length; i++) {
System.out.println(">" + words[i] + "<");
}
}
}
这实际上打印了我所期望的(没有返回空字符串):
$ run A
>aa<
>b<
但是...我做了几个完全让我困惑的测试:
System.out.println("a".split("\D+").length);
#=> 0 (WHY NOT 1? Empty string shouldn't be here?!)
System.out.println("a1".split("\D+").length);
#=> 2 (So now it splits to empty string and 1)
System.out.println("1a".split("\D+").length);
#=> 1 (now it returns expected "a" string)
所以我的问题是:
- 为什么要用我给出的例子拆分 returns 空字符串?
- 为什么
"a".split("\D+").length
returns 0 ? - 为什么
"a1".split("\D+").length
是 2(但没有一个) "1a".split("\D+").length)
与"a1".split("\D+").length)
有何不同 在分裂的情况下?
不匹配空字符串。相反,它匹配字符串开头的 "aa"
作为分隔符。第一个元素为空,因为在第一个分隔符之前只有一个空字符串。相反,对于尾随定界符,没有返回空字符串,如 documentation for split():
This method works as if by invoking the two-argument split method with the given expression and a limit argument of zero. Trailing empty strings are therefore not included in the resulting array.
- 为什么要用我给出的例子拆分 return 的空字符串?
'a'
不是数字,所以 aa
是分隔符。分隔符的两边都有 return 的元素,空字符串在 a
的左边。如果分隔符是 ","
,那么在字符串 ",a,b"
之外,您会期望有 3 个元素 -- ""
、"a"
和 "b"
。在这里,aa
是分隔符,就像我示例中的 ,
。
- 为什么
"a".split("\D+").length
returns 0 ?
'a'
不是数字,所以它是一个分隔符。分隔符的存在意味着在 a
的两边有两个从原始 String
中拆分出来的子串,均为空字符串。但是,no-arg split
method 会丢弃尾随的空字符串。它们都是空的,所以它们都被丢弃了,length
是0
。
- 为什么
"a1".split("\D+").length
是 2(而不是一个)
仅丢弃尾随的空字符串,因此元素为 ""
和 "1"
。
- 在拆分的情况下,
"1a".split("\D+").length
与"a1".split("\D+").length
有何不同?
"1a"
将丢弃一个尾随空字符串,但 "a1"
不会丢弃尾随空字符串(它是前导的)。