Split()拆分字串與StringTokenizer拆分字串
前言
不管用何種程式語言寫程式碼,對字串的處理都是必不可少的,其中對字串的拆分在許多場合都頻繁用到。
今天介紹Java中兩種主流的拆分方法,一是lang包String類的split()方法,另一種則是util包下的StringTokenizer類。
String.split()拆分字串
1.單引數拆分方法
public String[] split(String regex)
引數: regex-the delimiting regular expression,定界正則表示式
返回: String[],字串陣列,它是根據給定正則表示式的匹配拆分此字串確定的,如果表示式不匹配輸入的任何部分,那麼所得陣列只具有一個元素,即此字串。
丟擲: PatternSyntaxException - 如果正則表示式的語法無效
特點: 該方法的作用就像是使用給定的表示式和限制引數 0 來呼叫兩引數 split 方法,即是split(String regex,0)。因此,所得陣列中不包括結尾空字串。
拆分示例
拆分字串”Harry James Potter”,以空格進行拆分
package demotest;
public class SplitDemo {
public static void main(String[] args) {
String nameStr="Harry James Potter" ;
//"\\s"表示空格
String[] nameStrArray=nameStr.split("\\s");
//也可以來" "來進行拆分,這種方法要注意中間只能有一個空格,如果有兩個空格則不能正常拆分,最後得到的仍是原有字串
//String[] nameStrArray=nameStr.split(" ");
for(String name:nameStrArray){
System.out.println(name);
}
}
}
拆分結果
Harry James Potter
拆分後的字元陣列不包含節尾空字串
用單引數split()方法拆分字串時會發現有時拆分出來的字串陣列長度好像與預期不一致,這是因為當最後拆分出的那個字串為空字元時,這個空字元不會加到陣列中去。
示例:拆分”Harry#James#Potter###”,以”#”號進行拆分,按感覺來說應該會拆分成六段
package demotest;
import java.util.Arrays;
public class SplitDemo {
public static void main(String[] args) {
String nameStr="Harry#James#Potter###";
String[] nameStrArray=nameStr.split("#");
for(String name:nameStrArray){
System.out.println(name);
}
System.out.println("陣列長度為:"+nameStrArray.length);
System.out.println("陣列值為:"+Arrays.toString(nameStrArray));
}
}
執行結果如下:
Harry
James
Potter
陣列長度為:3
陣列值為:[Harry, James, Potter]
從結果來看,實際上拆分出的陣列只有三位,##之間與之後的空字串都不會被加入至這個陣列中。
2.雙引數拆分方法
public String[] split(String regex, int limit)
引數比上面方法多了一個int型別,limit 引數控制模式應用的次數,即拆分的次數,因此影響所得陣列的長度。下面n所指為limit引數
如果該限制 n 大於 0,則模式將被最多應用 n - 1 次,陣列的長度將不會大於 n,而且陣列的最後一項將包含所有超出最後匹配的定界符的輸入。
如果 n 為非正,那麼模式將被應用盡可能多的次數,而且陣列可以是任何長度。
如果 n 為 0,那麼模式將被應用盡可能多的次數,陣列可以是任何長度,並且結尾空字串將被丟棄。
limit為正負數時的示例
依舊以”Harry#James#Potter###”,以”#”號進行拆分
1.當limit為1時,拆分結果如下,陣列長度應不大於1,即小於等於1.
String nameStr="Harry#James#Potter###";
String[] nameStrArray=nameStr.split("#",1);
//結果如下,字串原樣輸出了,因為拆分只進行了1-1次,即0次
Harry#James#Potter###
陣列長度為:1
陣列值為:[Harry#James#Potter###]
2.當limit為4時,拆分了三次,陣列長度應不大於4.
String[] nameStrArray=nameStr.split("#",4);
//拆分結果如下,最後一個字串為"##",說明這兩個還沒被拆分
Harry
James
Potter
##
陣列長度為:4
陣列值為:[Harry, James, Potter, ##]
3.當limit為-1時,字串會被儘可能地被多拆分
String[] nameStrArray=nameStr.split("#",-1);
//拆分結果如下,陣列長度為6,其中包含了三個空字元,說明將所有的#都進行了拆分,字串不再有#存在
Harry
James
Potter
陣列長度為:6
陣列值為:[Harry, James, Potter, , , ]
4.當limit為-2時,拆分結果與-1時一致,所以當這個limit是負數時,不管傳什麼值,結果都是一致的。
String[] nameStrArray=nameStr.split("#",-1);
//拆分結果與-1時一致
Harry
James
Potter
陣列長度為:6
陣列值為:[Harry, James, Potter, , , ]
3.與str.split(regex,limit)結果相同的方法
以下運用字串匹配的方法與字串拆分方法返回的結果一致。
Pattern.compile(regex).split(str, n)
StringTokenizer類拆分字串
拆分原理
StringTokenizer拆分字串的原理是通過生成StringTokenizer物件,
然後運用物件的屬性來處理字串拆分的。
StringTokenizer類有三個建構函式,分別是一個引數,兩個引數,三個引數的建構函式。
public StringTokenizer(String str,String delim,boolean returnDelims)
public StringTokenizer(String str,String delim)
public StringTokenizer(String str)
建構函式為指定字串構造一個 string tokenizer。delim 引數中的所有字元都是分隔標記的分隔符,即是拆分的標識字串,以此字元對字串進行拆分。
如果 returnDelims 標誌為 true,則分隔符字元也作為標記返回。每個分隔符都作為一個長度為 1 的字串返回。如果標誌為 false,則跳過分隔符,只是用作標記之間的分隔符。
注意,如果 delim 為 null,則此構造方法不丟擲異常。但是,嘗試對得到的 StringTokenizer 呼叫其他方法則可能丟擲 NullPointerException。
引數:
str - 要解析的字串。
delim - 分隔符。
returnDelims - 指示是否將分隔符作為標記返回的標誌。丟擲:
NullPointerException - 如果 str 為 null。delim預設值 :當建構函式為一個引數時,tokenizer 使用預設的分隔符集 ” \t\n\r\f”,即:空白字元、製表符、換行符、回車符和換頁符。分隔符字元本身不作為標記。
拆分示例
1.單引數時,delim為預設值
package demotest;
import java.util.StringTokenizer;
public class StringTokenDemo {
public static void main(String[] args) {
String nameStr="Harry James Potter";
//將要拆分的字元傳入建構函式中,生成一個token物件
StringTokenizer strToken=new StringTokenizer(nameStr);
//當有拆分的子字串時,輸出這個字串
while(strToken.hasMoreTokens()){
System.out.println(strToken.nextToken());
}
}
}
執行結果
Harry
James
Potter
2.雙引數時,delim為”#”,拆分”Harry#James#Potter###”
//建構函式雙引數
StringTokenizer strToken=new StringTokenizer(nameStr,"#");
//執行結果
Harry
James
Potter
3.三引數時,returnDelims為true,返回作為分隔符的#號
//建構函式雙引數
StringTokenizer strToken=new StringTokenizer(nameStr,"#",true);
//執行結果,#號也作為strToken.nextToken()值被新增進去了。
Harry
#
James
#
Potter
#
#
#
推薦使用split進行字串拆分
從上面兩種方法的案例其實可以看出String.split()方法比StringTokenizer類的拆分方法更好便捷,也更好用。
畢竟大多數時候拆分得到的子字串是要進行操作的,而StringTokenizer類操作子字串是靠遍歷進行的,不僅麻煩,效率也低,相比之下運用陣列進行下標操作就方便多了,事實上官方也不推薦用StringTokenizer類生成物件的方法來進行字串的拆分操作了。