在Ja va日常开发中,String.split()是最常用的方法之一,但一遇到竖线|、点号.这类特殊符号,就很容易出问题。说到底,split()的参数本质上是一个正则表达式,而竖线|在正则里是“或”操作符——这一点才是问题的根源。

竖线 | 必须用双反斜杠转义
举个例子,直接写"a|b".split("|")会变成什么?结果可能出乎意料——它会把字符串拆成每个字符,因为空字符串也能匹配上。最终你会得到一个类似["", "a", "", "b", ""]的数组。要按字面意义切分,得写成"|":
- 正确写法:
"a|b|c".split("|")→ 得到["a", "b", "c"] - 原理其实很简单:Ja va字符串里
"|"先被转成|传给正则引擎,正则引擎收到后,把|当作字面量竖线来处理 - 千万别写成
"|"或"|"——前者编译会报错,后者属于过度转义,匹配可能失败
点号 . 同样要双反斜杠转义
点号 . 在正则里代表“任意字符”,所以 "a.b.c".split(".") 会按每个字符的位置切分,结果是一堆空串和单字符。正确的做法是写成 ".":
- 正确写法:
"a.b.c".split(".")→ 得到["a", "b", "c"] - 注意:只写
"."会报Ja va语法错误;写"\."虽然也能工作,但没必要那么冗余 - 其他常见需要转义的符号同理:星号
*要写成"*",加号+写成"+",问号?写成"?"
更安全的做法:用 Pattern.quote()
如果不确定某个符号是否需要转义,或者分隔符是动态拼接的,那么 Pattern.quote() 是最省心的选择——它会自动将任意字符串转成正则字面量形式:
"a|b.c".split(Pattern.quote("|"))→ 得到["a", "b.c"]"a|b.c".split(Pattern.quote("."))→ 得到["a|b", "c"]- 这个方法特别适合分隔符来自用户输入或配置文件的场景,手动转义容易出错,不如交给工具处理
补充:空字符串和连续分隔符的处理
转义问题搞定之后,还有一个细节需要注意。split() 默认会丢弃末尾的空项。比如 "a||b|".split("|") 返回的是 ["a", "", "b"],末尾那个空串被去掉了:
- 如果想保留所有项(包括结尾的空串),可以加一个负数参数:
split("|", -1) "a||b|".split("|", -1)会返回["a", "", "b", ""]- 如果只想要非空项,后续可以用
Arrays.stream(arr).filter(s -> !s.isEmpty()).toArray(String[]::new)来过滤