java 的split函数接受一个正则表达式的分隔符为参数,将string按照分隔符划分为一个数组。我们可能会忽略这个参数的要求,这里传入的分隔符并不是一个普通的字符串,而是一个正则表达式。
最常见的情景,比如“a.b”,分割为“a”和“b”,如果我们不注意,会写成s.split("."),结果是不对的,因为"."是被当做一个正则表达式来看的,它有特殊含义,表示“任意单个字符”,所以结果肯定不是我们想要的。事实上最后会返回空,不知道为什么。。。
接着上网一查,发现了需要转义,也就是“\\.”,结果果然是对的。
这里我想搞清楚为什么是两个斜杠。
需要明白两点。
第一,在java的字符串中,反斜杠是由特殊含义的,它的存在只是为了表明它后面的一个字符需要做特殊处理而非原本的意思。比如“\n”是换行。如果我们要使用反斜杠本来的含义呢?需要用两个反斜杠。而且,反斜杠不是随便可以使用的,只能用在六种情况下,即只能对六种字符转义,不能单独出现或者转义其他字符。
比如定义了
String s = "\y";
就会提示编译错误:“
Invalid escape sequence (valid ones are \b \t \n \f \r \" \' \\ ”,说明反斜杠只能在这六种情况下转义。
这是java字符串层面上的反斜杠。
第二,在正则表达式里。反斜杠也有特殊含义,正则表达式有一套自己的规定,这个规定是脱离语言层面的。比如“*”表示重复任意次。“\d”表示一个数字等。我们想在java里面写出一个正则字符串,可能需要用到反斜杠,这时就需要注意java语言里的string对反斜杠的特殊限制,也就是第一点。
我们想定义一个“\d”,就需要在“d”前面加一个反斜杠,但是一个反斜杠在java里会被当做转义符,所以我们需要再加一个反斜杠。第一个是正则表达式的要求,第二个是java语言里的要求。
有人会问,既然一个反斜杠就是转义符,那么为什么“\d”没有把“d”转义成功呢?因为,在java语言里面,反斜杠只能转义前面提到的六种字符,这里的“\d”是正则表达式的规定,并不是java语言的规定,java语言内部是不知道“\d”也需要转义,不知道这是一个正则表达式,他只知道这个是一个字符串。只要我们程序的编写者或者说正则表达式的类库编写者和使用者,才会把这个字符串当做一个正则表达式来看。
所以,为什么会有两个反斜杠是因为它们代表了来两个层面的含义,一个是java语言的转义符,一个是正则表达式的规定。