[Java] String.split()的用法

本文讨论Java中的split函数.

split()是一个用来切分字符串的函数, 相信大家都用过, 但是, 可能他不是你想象中的那么简单.


解析

public String[] split(String regex)

public String[] split(String regex, int limit)
  • regex参数

一般来说, String类型的形参名不应该叫str或者string吗? 为什么这里要用regex呢? 可能是因为regex有实际的含义, regex又是什么意思呢? regular expression, 正则表达式啊. 看到正则表达式, 很多人就比较熟悉了吧. 也就是说, regex参数不仅仅是一个简单的字符串, 而是一个正则表达式.

  • limit参数

该参数用于控制匹配的次数. public String[] split(String regex)为limit为0的情况.

limit > 0 : 最多匹配limit-1次,得到一个长度为limit的数组. String[limit-1]为余下未匹配的字符串

limit = 0 : 尽可能的多匹配, 且长度无限制, 但结尾空字符串将被丢弃

limit < 0 : 尽可能的多匹配, 且长度无限制


最基本的用法

最基本的用法当然就是用指定字符串直接分割代码, 一般来说是一个符号之类的, 代码简单, 不多解释.

String string = "hello, world!";
String[] strings = string.split(",");

for (String str : strings) {
	System.out.println(str);
}

输出结果为(注意空格! ) :

hello
world!


limit参数的用法

  • 默认情况(即limit = 0)

先看下面这段代码, 字符串数组长度是多少? 也许大多人觉得长度是7吧. 但实际上, 是5. 我们看输出结果, d后面就没有了, 为什么开头的空字符串能分割出来但是结尾的却没了? 请看解析中说过的limit参数.

String string = ",a,b,c,d,,";
String[] strings = string.split(",");
System.out.println(strings.length);

for (String str : strings) {
	System.out.println(str);
}

输出结果为:

5

a
b
c
d


  • limit < 0

现在再来看看这段代码. 下面这段代码和上面那段代码相比, 就改了一个地方: 加了一个小于0的limit参数. 现在我们看到的结果, 才和我们的预期一样.

也就是说, 如果切割后的字符串数组尾部出现空字符串的情况, 不加limit参数会省略末尾的空字符串, 其他位置的空字符串不受影响.

当我们加了一个小于0 的参数以后, 则不会丢弃字符串数组末尾的空字符串.

String string = ",a,b,c,d,,";
String[] strings = string.split(",", -1);// 唯一变动在这
System.out.println(strings.length);

for (String str : strings) {
	System.out.println(str);
}

输出结果为(注意, strings的长度为7, d的后面还有两行, 但是由于什么都没有, 知乎直接给你咔嚓了末尾的空白行) :

7

a
b
c
d


  • limit > 0

最后我们来看看limit > 0的情况. 我们给的字符串中一共有6个逗号, 我们给limit赋值为4, 也就是让他最多匹配三次. 剩下未匹配的内容全都丢进strings[3]里面.

匹配第一个逗号得到: {"", "a,b,c,d,,"}

匹配第二个逗号得到: {"", "a", "b,c,d,,"}

匹配第三个逗号得到: {"", "a", "b", "c,d,,"}

String string = ",a,b,c,d,,";
String[] strings = string.split(",", 4);
System.out.println(strings.length);

for (String str : strings) {
	System.out.println(str);
}

输出结果为 :

4

a
b
c,d,,


正则表达式元字符

  • 一个错误的示例

所有的标点都能直接分割字符串吗? 当然不是, 比如说 . 这个符号就不能, 如果按照下面的代码这样写的话, 会出现一些我不知道的情况.

String string = ".a.b.c.d..";
String[] strings = string.split(".");
System.out.println(strings.length);

for (String str : strings) {
	System.out.println(str);
}

输出结果为:

0


  • 元字符分割字符串的用法

我们需要做的就是, 把 . 这个符号给转义. 下面代码才是将 . 这个符号当成一个分隔符使用.

同样的, 还有 | $ ( ) [ { ^ ? * + \\ 等符号(这些符号是正则表达式元字符), 不能直接分割字符串使用, 想要用元字符分割的话, 得用 \\ 转义, 用类似于split("\\|")的方法.

String string = ".a.b.c.d..";
String[] strings = string.split("\\.");
System.out.println(strings.length);

for (String str : strings) {
	System.out.println(str);
}

输出结果为:

5

a
b
c
d


  • 元字符 | 的正确用法

下面的才是 | 的正确用法

String string = "a=1 and a=2 or a=3";
String[] strings = string.split("and|or");

for (String str : strings) {
	System.out.println(str);
}

输出结果为:

a=1
a=2
a=3


  • 使用 \ 分割字符串

这个就比较麻烦了, 先看代码吧. 定义字符串的时候就不能像"aa\bb\cc"这样定义, 会报错, 要用 \\ 转义才行. 如果我们想要表达的字符串是"aa\bb\cc", 要定义成"aa\\bb\\cc", 计算机才看得懂. 第二行的四个反斜杠相信大家也明白是怎么回事了

String string = "aa\\bb\\cc";
String[] strings = string.split("\\\\");
System.out.println(strings.length);

for (String str : strings) {
	System.out.println(str);
}

输出结果为:

aa
bb
cc


一些其他元字符的用法

  • \d 数字
  • \D 非数字
  • \s 空白字符
  • \S 非空白字符
  • \w 单词字符
  • \W 非单词字符
  • ......

如何获取一个句子中的所有单词(也就是以非单词作为分隔符) ? 直接看下面的代码吧. \\W 代表以非单词字符分割, 只要是正则表达式元字符都行. 用括号括起来, 再跟一个 + 表示一个或多个非单词分隔符.

String string = "hello,,, world!";
String[] strings = string.split("[\\W]+");
System.out.println(strings.length);

for (String str : strings) {
	System.out.println(str);
}

输出结果为:

2
hello
world


若是直接以 \\W 作为分割符而不是 [\\W]+ , 则是下面的输出

5
hello



world

参考:

String的split()方法的两种使用方式 - CSDN博客

Java String.split()用法小结

Java中字符串split() 的使用方法.没你想的那么简单

编辑于 2018-09-23