前面介紹了處理字符串的經常使用方法,還有一種分割字符串的場景也很常見,也就是按照某個規則將字符串切割爲若干子串。分割規則一般是指定某個分隔符,根據字符串內部的分隔符將字符串進行分割,例如逗號、空格等等均可以做爲字符串的分隔符。正好String類型提供了split方法用於切割字符串,只要字符串變量調用split方法,並把分隔符做爲輸入參數,該方法便可返回分割好的字符串數組。
下面的split調用代碼例子演示瞭如何按照逗號和空格切割字符串:html
// 經過逗號分割字符串 private static void splitByComma() { String commaStr = "123,456,789"; // 利用split方法指定按照逗號切割字符串 String[] commaArray = commaStr.split(","); for (String item : commaArray) { System.out.println("comma item = "+item); } } // 經過空格分割字符串 private static void splitBySpace() { String spaceStr = "123 456 789"; // 利用split方法指定按照空格切割字符串 String[] spaceArray = spaceStr.split(" "); for (String item : spaceArray) { System.out.println("space item = "+item); } }
除了逗號和空格之外,點號和豎線也經常用來分隔字符串,可是對於點號和豎線,split方法的調用代碼不會獲得預期的結果。相反,split(".")沒法獲得分割後的字符串數組,也就是說結果的字符串數組爲空;而split("|")分割獲得的字符串數組,每一個數組元素只有一個字符,其結果相似於toCharArray。究其緣由,緣於split方法的輸入參數理應是個正則串,並不是普通的分隔字符。因爲點號和豎線都是正則串的保留字符,所以沒法直接在正則串中填寫,必須進行轉義處理方可。如同回車符和換行符在普通字符串中經過前綴的反斜杆轉義那樣(回車符對應\r,換行符對應\n),正則字符串經過在原字符前面添加兩個反斜杆來轉義,像點號字符在正則串中對應的轉義符爲「\\.」,而豎線在正則串中對應的轉義符爲「\\|」。通過轉移處理以後,經過點號和豎線切割字符串的正確代碼寫法以下所示:java
// 經過點號分割字符串 private static void splitByDot() { String dotStr = "123.456.789"; // split(".")沒法獲得分割後的字符串數組 //String[] dotArray = dotStr.split("."); // 點號是正則串的保留字符,須要進行轉義(在點號前面加兩個反斜杆) String[] dotArray = dotStr.split("\\."); for (String item : dotArray) { System.out.println("dot item = "+item); } } // 經過豎線分割字符串 private static void splitByLine() { String lineStr = "123|456|789"; // split("|")分割獲得的字符串數組,每一個數組元素只有一個字符,相似於toCharArray的結果 //String[] lineArray = lineStr.split("|"); // 豎線是正則串的保留字符,須要進行轉義(在豎線前面加兩個反斜杆) String[] lineArray = lineStr.split("\\|"); for (String item : lineArray) { System.out.println("line item = "+item); } }
豎線符號之因此被定爲正則串的保留字符,是由於它在正則表達式裏起到了「或」的判斷做用,例如正則串「,| 」表示逗號和空格都是知足條件的分隔符;一個字符串若是同時包含一個逗號和一個空格,那麼按照「,| 」切割的結果將是長度爲3的字符串數組;也就是說,原始串被逗號分割一次後又被空格分割一次,這樣一共分割兩次最終獲得了三個子串。下面的代碼演示了使用正則串「,| 」切割字符串的效果:正則表達式
// 利用豎線同時指定多個串來分割字符串 private static void splitByMixture() { String mixtureStr = "123,456 789"; // 正則串裏的豎線表示「或」,豎線左邊和右邊的字符均可以用來分割字符串 String[] mixtureArray = mixtureStr.split(",| "); for (String item : mixtureArray) { System.out.println("mixture item = "+item); } }
固然,正則串中的保留字符不只包括點號和豎線,還包括好些常見的符號,好比加號(+)、星號(*)、橫線(-),在正則串中均需進行轉義。其中加號的正則轉義符爲「\\+」,星號的正則轉義符爲「\\*」,橫線的正則轉義符爲「\\-」。這麼估摸下,加減乘除的四則運算符號,只有除法的斜杆符(/)、取餘數的百分號(%)無需轉義處理。假若有個字符串,要求以四則運算的五個符號進行切割,則需經過豎線把這幾個轉義後的字符加以鏈接,構成形如「\\+|\\*|\\-|/|%」的正則串。因而按照加減乘除符號切割字符串的代碼就變爲下面這樣:數組
// 經過算術的加減乘除符號來分割字符串 private static void splitByArith() { String arithStr = "123+456*789-123/456%789"; // 正則串裏的加號、星號、橫線都要轉義,加減乘除符號之間經過豎線隔開 String[] arithArray = arithStr.split("\\+|\\*|\\-|/|%"); for (String item : arithArray) { System.out.println("arith item = "+item); } }
分割用的正則串,不僅僅是一個個字符,還支持好幾個字符組成的字符串。譬如「(1)」、「(2)」、「(3)」均可以做爲分隔串,注意圓括號內部的數字能夠是0到9,如此一來,從「(0)」到「(9)」的分隔串合集豈不是要寫成如下這般:「(0)|(1)|(2)|(3)|(4)|(5)|(6)|(7)|(8)|(9)」?然而以上正則串的寫法有兩個錯誤:
一、圓括號也是正則表達式的保留字符,因此不能直接在正則串中書寫「(」和「)」,而必須寫成轉義形式「\\(」和」「\\)」。
二、做爲保留字符的圓括號,其做用相似數值計算之時的圓括號,都是經過圓括號把括號內外的運算區分開。而豎線符號「|」的或運算優先級不如圓括號,所以每逢複雜一點的或運算,應當把圓括號放在整個邏輯運算式子的外面。
綜合以上兩點,修正以後的正則串應該改爲下列形式:「\\((0|1|2|3|4|5|6|7|8|9)\\)」。但是該式子的豎線太多,意思僅僅是獲取0到9之間的某個數字之一,針對這種狀況,正則表達式引入了另一種簡化的寫法,即經過方括號包裹0123456789,形如「\\([0123456789]\\)」,一樣指代0到9之間的某個數字,從而省略了若干個豎線。進一步說,平常生活中0到9,經常寫作「0-9」,因而對應更簡單的正則串「\\([0-9]\\)」。
其實0到9正好涵蓋了全部的一位數字,對於一位數字而言,正則表達式提供了專門的表達式「\\d{1}」。式子前面的「\\d」表明某個數字,式子後面的「{1}」表明字符數量是1位。推而廣之,「\\d{2}」表示兩位數字,「\\d{3}」表示三位數字,等等。像這個正則例子只有一位數字,甚至尾巴的「{1}」均可以去掉,由於「\\d」默認就是一位數字。
一口氣介紹了許多種從0到9的正則表達串,接下來不妨逐一驗證這些正則串是否有效,驗證用的代碼例子以下所示:spa
// 經過圓括號及其內部數字來分割字符串 private static void splitByBracket() { String bracketStr = "(1)123;(2)456;(3)789;"; // 圓括號也是正則串的保留字符,0到9這九個數字使用豎線隔開 //String[] bracketArray = bracketStr.split("\\((0|1|2|3|4|5|6|7|8|9)\\)"); // 利用方括號彙集一羣字符,表示這些字符之間是「或」的關係,故而可省略豎線 //String[] bracketArray = bracketStr.split("\\([0123456789]\\)"); // 連續的數字可以使用橫線鏈接首尾數字,例如「0-9」表示從0到9之間的全部數字 //String[] bracketArray = bracketStr.split("\\([0-9]\\)"); // 利用「\\d」便可表達0到9的數字,後面的{1}表示1位數字,依此類推{3}表示三位數字 //String[] bracketArray = bracketStr.split("\\(\\d{1}\\)"); // 「\\d」默認就是1位數字,此時後面的{1}可直接略去 String[] bracketArray = bracketStr.split("\\(\\d\\)"); for (String item : bracketArray) { System.out.println("bracket item = "+item); } }
上述的幾種正則串,只能表達從「(0)」到「(9)」的分隔串,然而圓括號內部還多是兩位數字或者三位數字,好比「(10)」、「(12)」、「(001)」這樣。對於數字位數不固定的狀況,能夠把「\\d」改成「\\d+」,末尾多出來的加號,表示前面的字符容許有一位,也容許有多位。此時正則串添加了加號的字符串切割代碼見下:htm
// 經過特殊符號的加號來分割字符串 private static void splitWithPlus() { String bracketStr = "(1)123;(2)456;(13)789;"; // 正則串裏的加號表示能夠有1到多個前面的字符 String[] bracketArray = bracketStr.split("\\(\\d+\\)"); for (String item : bracketArray) { System.out.println("plus item = "+item); } }
上面說的位數不固定,畢竟至少還有一位。假設如今某個字符不但位數不肯定,甚至還可能沒有該字符(位數爲0),採用寫法「\\d+」就沒法奏效了。要想知足位數無關緊要的狀況,需將末尾的加號換成星號,也就是改爲「\\d*」,此時改用星號的字符串切割代碼變爲下面這般:blog
// 經過特殊符號的星號來分割字符串 private static void splitWithStar() { String bracketStr = "()123;(2)456;(13)789;"; // 正則串裏的星號表示能夠有0到多個前面的字符 String[] bracketArray = bracketStr.split("\\(\\d*\\)"); for (String item : bracketArray) { System.out.println("star item = "+item); } }
到目前位置,分隔符還僅限於標點和數字,若是引入英文字母做爲分隔串,又該如何書寫呢?注意英文字母區分大小寫,於是使用「a-z」表示全部的小寫字母,使用「A-Z」表示全部的大寫字母。若是採納「(a)」、「(B)」、「(c)」這種大小寫混合的分隔串,就得經過正則串「\\([a-zA-Z]\\)」來表達,對應的字符串切割代碼以下所示:開發
// 經過大小寫字母來分割字符串 private static void splitWithLetter() { String bracketStr = "(a)123;(B)456;(c)789;"; // 在正則串中表達小寫字母和大寫字母 String[] bracketArray = bracketStr.split("\\([a-zA-Z]\\)"); for (String item : bracketArray) { System.out.println("letter item = "+item); } }
如今有個麻煩的業務場景,圓括號內部不但多是數字和字母,還多是其它標點符號,這下難不成把衆多標點符號一個個羅列出來?要知道標點符號可沒有「0-9」、「a-z」、「A-Z」的簡單寫法噢。不過這難不倒強大的正則表達式,由於點號做爲正則的保留字符,它表明了除回車\r和換行\n之外的其它字符,因此使用「\\(.\\)」便可表達符合要求的任意字符了,固然是被圓括號包裹着的、除了回車\r和換行\n之外的任意字符。下面即是匹配前述場景的字符串切割代碼例子:字符串
// 經過特殊符號的點號來分割字符串 private static void splitWithDot() { String bracketStr = "(1)123;(B)456;(%)789;"; // 正則串裏的點號表示除了回車\r和換行\n之外的其它字符 String[] bracketArray = bracketStr.split("\\(.\\)"); for (String item : bracketArray) { System.out.println("dot item = "+item); } }
更多Java技術文章參見《Java開發筆記(序)章節目錄》get