1. 程式人生 > 其它 >JAVA中字串的split方法有兩個陷阱需要注意

JAVA中字串的split方法有兩個陷阱需要注意

技術標籤:JAVAjava字串

JAVA中字串的split方法有兩個陷阱需要注意

在開發過程中,我們會碰到一種場景,需要對字串進行分割,從而得到更具體的資訊。

比如下面這個字串:

String str = "123455#JAVA程式設計思想#這是一本JAVA聖經級別的書籍!";

該字串包含書籍ID、書籍名稱以及簡介,三條資訊用#號連線在一起。

想要得到這三條資訊,我們通常使用split方法:

String[] strArray = str.split("#");
for (int i = 0; i < strArray.length;
i++) { System.out.println(strArray[0]);// 書籍ID System.out.println(strArray[1]);// 書籍名稱 System.out.println(strArray[2]);// 簡介 }

split使用很簡單,但一不小心,很容易掉進兩個陷阱:

split的引數是正則表示式,不是字串物件

當大家看到str.split("#")時,很容易誤解#是一個字串物件,實際上JDK中 split方法定義的是正則表示式。

所以當要分割的字串是正則表示式中的特殊符號時,執行split方法就不會得到預期的結果。

比如分隔符由#變為 |

String str = "123455|JAVA程式設計思想|這是一本JAVA聖經級別的書籍!";

String[] strArray = str.split("|");
for (int i = 0; i < strArray.length; i++) {
    System.out.println(i + " >> " + strArray[i]);
}

執行結果是:

0 >> 1
1 >> 2
2 >> 3
3 >> 4
4 >>
5 5 >> 5 6 >> | 7 >> J 8 >> A 9 >> V 10 >> A 11 >> 編 12 >> 程 13 >> 思 14 >> 想 15 >> | 16 >> 這 17 >> 是 18 >> 一 19 >> 本 20 >> J 21 >> A 22 >> V 23 >> A 24 >> 聖 25 >> 經 26 >> 級 27 >> 別 28 >> 的 29 >> 書 30 >> 籍 31 >>

要解決這個問題,有兩種方法:

1、對特殊字元做轉義

正則表示式中轉義是\ ,所以split的引數應該是\|,然而\ 在JAVA中也是轉義字元,即也是特殊字元,也需要轉移,所以最終split的引數是\\|

修改後的程式碼就是:

String str = "123455|JAVA程式設計思想|這是一本JAVA聖經級別的書籍!";

String[] strArray = str.split("\\|");
for (int i = 0; i < strArray.length; i++) {
    System.out.println(i + " >> " + strArray[i]);
}

2、將特殊字元放在中括號中

正則表示式中,中括號是用來定義匹配的字元範圍。

修改後的程式碼是:

String str = "123455|JAVA程式設計思想|這是一本JAVA聖經級別的書籍!";

String[] strArray = str.split("[|]");
for (int i = 0; i < strArray.length; i++) {
    System.out.println(i + " >> " + strArray[i]);
}

使用split方法時,有的特殊字元需要注意,那哪些字元需要特別關注呢?

正則表示式中有11個特殊字元:^$|.*+?(){}\/

除了/之外,直接用其他特殊字元分割字串,都不會得到預期的結果。

甚至在使用*+?{}作為分割字串時,編譯就報錯,強制我們去做轉義。

為了保證split分割的結果是正確的,也為了減少記憶特殊字串的麻煩,我建議大家在使用split時,就將分割字串放在中括號中。即使用第二種方式:

String[] strArray = str.split("[|]");

split分割後的陣列長度可能小於預期的長度

對字串進行分割後,我們可能會將這些資訊賦值給一個物件,比如:

String str = "123455#JAVA程式設計思想#這是一本JAVA聖經級別的書籍!";

String[] strArray = str.split("[#]");
Book book = new Book();
book.setId(strArray[0]);
book.setName(strArray[1]);
book.setDesc(strArray[2]);

一般情況下這是沒有問題的,但是如果分割的字串最後沒有書籍簡介,就會出問題:

String str = "123455#JAVA程式設計思想#";

String[] strArray = str.split("[#]");
for (int i = 0; i < strArray.length; i++) {
    System.out.println(i + " >> " + strArray[i]);
}

執行程式碼的結果是:

0 >> 123455
1 >> JAVA程式設計思想

也就是分割後的陣列長度是2,而我們預期的長度是3,所以執行book.setDesc(strArray[2])程式碼就會報錯。

如果想讓上面的字串分割後的陣列長度為3,應該怎麼處理?split方法中提供了第二個引數:

String str = "123455#JAVA程式設計思想#";

String[] strArray = str.split("[#]", 3);
for (int i = 0; i < strArray.length; i++) {
    System.out.println(i + " >> " + strArray[i]);
}

執行程式碼的結果是:

0 >> 123455
1 >> JAVA程式設計思想
2 >> 

檢視JDK的原始碼,可以發現split只傳一個引數時,實際上第二個引數預設傳的是0。
在這裡插入圖片描述
當第二個引數limit的值大於0時,表示將字串分割為幾段(也就是陣列長度),但這個長度也不能大於字串中分割字串的個數+1。

String str = "a##b#";
String[] arr1 = str.split("[#]", 2);
/**
分割後的陣列為:
arr1[0] = "a";
arr1[1] = "#b#";
*/

String[] arr2 = str.split("[#]", 3);
/**
分割後的陣列為:
arr2[0] = "a";
arr2[1] = "";
arr2[2] = "b#";
*/

String[] arr3 = str.split("[#]", 4);
/**
分割後的陣列為:
arr3[0] = "a";
arr3[1] = "";
arr3[2] = "b";
arr3[3] = "";
*/

String[] arr4 = str.split("[#]", 5);
/**
字串中的#有3個,最多能分割成長度為4的陣列,所以第二個引數傳5時,結果和傳4是一樣的:
arr4[0] = "a";
arr4[1] = "";
arr4[2] = "b";
arr4[3] = "";
*/

當第二個引數limit的值小於0時,結果就有些出人意料了,得到的陣列是完全按照指定字元分割的。

String str = "a##b#";
String[] arr1 = str.split("[#]", -1);
/**
分割後的陣列為:
arr1[0] = "a";
arr1[1] = "";
arr1[2] = "b";
arr1[3] = "";
*/

總結

1、在使用split對字串進行分割時,將分隔符放在中括號中。str.split("[|]")

2、當要通過陣列遊標獲取分割後的資訊時,split第二個引數傳入一個負值。str.split('[|]', -1)

注意到這兩點,你在使用split方法時就絕對不會出錯啦!

看到這裡,你是否應該馬上搜索程式碼,看看split的使用都正確了?如果沒有,立即改正吧!

ps:
如果文章對你有幫助,請關注我的公眾號吧!
在這裡插入圖片描述