1. 程式人生 > >關於java中split的使用

關於java中split的使用

   之前在http://shukuiyan.iteye.com/blog/507915文中已經敘述過這個問題,但是最近一次筆試中居然有碰到了這個知識點,而且還做錯了,囧!學藝不精啊。題目大概是這樣的:

Java程式碼  收藏程式碼
  1. String s2="this is a test";  
  2. String sarray[]=s2.split("/s");  
  3. System.out.println("sarray.length="+sarray.length);  

這個輸出是什麼還是編譯出錯?我想那個split方法中的引數要是"s"的話,輸出一定是4了,就是將原來字串分成了陣列{"thi","i","a te","t"},但是原題split方法中的引數要是"/s",那麼這個引數到底是嘛意思呢,實驗後輸出結果居然是1。

原因還得深究啊。

    java.lang.string.split,即split 方法,它實現的功能是將一個字串分割為子字串,然後將結果作為字串陣列返回。 格式為:

                 stringObj.split([separator,[limit]]) 
其中stringObj是必選項,表示要被分解的 String 物件或文字。該物件不會被 split 方法修改。 separator 為可選項,表示字串或正則表示式物件,它標識了分隔字串時使用的是一個還是多個字元。如果忽略該選項,返回包含整個字串的單一元素陣列。 limit 為可選項,該值用來限制返回陣列中的元素個數。 值得注意的是: split 方法的結果是一個字串陣列,在 stingObj 中每個出現 separator 的位置都要進行分解,separator 不作為任何陣列元素的部分返回。

一個例子

Java程式碼  收藏程式碼
  1. String srcstring="this is a about split test";  
  2. String stringarray[]=srcstring.split(" ");  
  3. //// 在每個空格字元處進行分解  
  4. for(String stemp:stringarray){  
  5.     System.out.println(stemp);  
  6. }  
  7. String srcstring1=" this  is a about split  test";//有n個空格的話,分成的陣列長度為n+1  
  8. //如果字串中有多個空格時,則兩個空格間認為是沒有字元,結果字串陣列中該位置為空。
      
  9. String stringarray1[]=srcstring1.split(" ");  
  10. for(String stemp:stringarray1){  
  11.     System.out.println(stemp);  
  12. }  

這樣輸出結果為

Java程式碼  收藏程式碼
  1. this  
  2. is  
  3. a  
  4. about  
  5. split  
  6. test  
  7. 另一個:  
  8. this  
  9. is  
  10. a  
  11. about  
  12. split  
  13. test  

另外一個例子

Java程式碼  收藏程式碼
  1. String srcstring="this is a about split test";  
  2. String stringarray[]=srcstring.split(" ",2);  
  3. //// 在每個空格字元處進行分解  
  4. for(String stemp:stringarray){  
  5.        System.out.println(stemp);  
  6. }  
  7. 輸出結果為  
  8. this  
  9. is a about split test  

 看看下面這個

Java程式碼  收藏程式碼
  1. String ipstring="59.64.159.224";  
  2. String iparray[]=ipstring.split(".");  
  3. for(String stemp:iparray){  
  4.     System.out.println(stemp);  
  5. }  
  6. 這個輸出為空,為什麼呢?  

因為 public string[] split(string regex) 這裡的引數的名稱是regex ,也就是 regular expression (正則表示式)。這個引數並不是一個簡單的分割用的字元,而是一個正則表示式,以下是split 方法的實現程式碼:
   public string[] split(string regex, int limit) { 
        return pattern.compile(regex).split(this, limit); 
   }

split 的實現直接呼叫的 matcher 類的 split 的方法。我們知道,“ . ”在正則表示式中有特殊的含義,因此我們使用的時候必須進行轉義。 只要將

Java程式碼  收藏程式碼
  1. String iparray[]=ipstring.split(".");  

改為

Java程式碼  收藏程式碼
  1. String iparray[]=ipstring.split("\\.");  


就可以了。

那麼這裡在列上一些轉義字元

 \\ 反斜槓 
\t 間隔 ('\u0009')
\n 換行 ('\u000A')
\r 回車 ('\u000D')
\d 數字 等價於 [0-9]
\D 非數字 等價於 [^0-9]
\s 空白符號 [\t\n\x0B\f\r]
\S 非空白符號 [^\t\n\x0B\f\r]
\w 單獨字元 [a-zA-Z_0-9]
\W 非單獨字元 [^a-zA-Z_0-9]
\f 換頁符 
\e Escape
\b 一個單詞的邊界 
\B 一個非單詞的邊界 
\G 前一個匹配的結束

注意:public String[] split(String regex,int limit)根據匹配給定的正則表示式來拆分此字串。 
此方法返回的陣列包含此字串的每個子字串,這些子字串由另一個匹配給定的表示式的子字串終止或由字串結束來終止。陣列中的子字串按它們在此字串中的順序排列。如果表示式不匹配輸入的任何部分,則結果陣列只具有一個元素,即此字串。 

limit 引數控制模式應用的次數,因此影響結果陣列的長度。如果該限制 n 大於 0,則模式將被最多應用 n - 1 次,陣列的長度將不會大於 n,而且陣列的最後項將包含超出最後匹配的定界符的所有輸入。如果 n 為非正,則模式將被應用盡可能多的次數,而且陣列可以是任意長度。如果 n 為零,則模式將被應用盡可能多的次數,陣列可有任何長度,並且結尾空字串將被丟棄。

回到最初的題目,題目中給出的匹配正則表示式為"/s",表示空白字元,此時給定的字串中沒有匹配的字元,則輸出為原字串,所以輸出的字元長度為1.

再附上一些關於java中正則表示式的知識吧

^ 為限制開頭 
^java     條件限制為以 Java 為開頭字元 
$ 為限制結尾 
java$     條件限制為以 java 為結尾字元 
.  條件限制除 \n 以外任意一個單獨字元 
java..     條件限制為 java 後除換行外任意兩個字元

加入特定限制條件「 [] 」 
[a-z]     條件限制在小寫 a to z 範圍中一個字元 
[A-Z]     條件限制在大寫 A to Z 範圍中一個字元 
[a-zA-Z] 條件限制在小寫 a to z 或大寫 A to Z 範圍中一個字元 
[0-9]     條件限制在小寫 0 to 9 範圍中一個字元 
[0-9a-z] 條件限制在小寫 0 to 9 或 a to z 範圍中一個字元 
[0-9[a-z]] 條件限制在小寫 0 to 9 或 a to z 範圍中一個字元 ( 交集 )

[] 中加入 ^ 後加再次限制條件「 [^] 」 
[^a-z]     條件限制在非小寫 a to z 範圍中一個字元 
[^A-Z]     條件限制在非大寫 A to Z 範圍中一個字元 
[^a-zA-Z] 條件限制在非小寫 a to z 或大寫 A to Z 範圍中一個字元 
[^0-9]     條件限制在非小寫 0 to 9 範圍中一個字元 
[^0-9a-z] 條件限制在非小寫 0 to 9 或 a to z 範圍中一個字元 
[^0-9[a-z]] 條件限制在非小寫 0 to 9 或 a to z 範圍中一個字元 ( 交集 )

在限制條件為特定字元出現 0 次以上時,可以使用「 * 」 
J*     0 個以上 J
.*     0 個以上任意字元 
J.*D     J 與 D 之間 0 個以上任意字元 

在限制條件為特定字元出現 1 次以上時,可以使用「 + 」 
J+     1 個以上 J
.+     1 個以上任意字元 
J.+D     J 與 D 之間 1 個以上任意字元 

在限制條件為特定字元出現有 0 或 1 次以上時,可以使用「 ? 」 
JA?     J 或者 JA 出現

限制為連續出現指定次數字符「 {a} 」 
J{2}     JJ
J{3}     JJJ
文字 a 個以上,並且「 {a,} 」 
J{3,}     JJJ,JJJJ,JJJJJ,???(3 次以上 J 並存 )
文字個以上, b 個以下「 {a,b} 」 
J{3,5}     JJJ 或 JJJJ 或 JJJJJ
兩者取一「 | 」 
J|A     J 或 A
Java|Hello     Java 或 Hello

「 () 」中規定一個組合型別 
比如,我查詢 <a href=\"index.html\">index</a> 中 <a href></a> 間的資料,可寫作 <a.*href=\".*\">(.+?)</a>

在使用 Pattern.compile 函式時,可以加入控制正則表示式的匹配行為的引數: 
Pattern Pattern.compile(String regex, int flag)

flag 的取值範圍如下: 
Pattern.CANON_EQ     當且僅當兩個字元的 " 正規分解 (canonical decomposition)" 都完全相同的情況下,才認定匹配。比如用了這個標誌之後,表示式 "a\u030A" 會匹配 "?" 。預設情況下,不考慮 " 規範相等性 (canonical equivalence)" 。 
Pattern.CASE_INSENSITIVE(?i)     預設情況下,大小寫不明感的匹配只適用於 US-ASCII 字符集。這個標誌能讓表示式忽略大小寫進行匹配。要想對 Unicode 字元進行大小不明感的匹配,只要將 UNICODE_CASE 與這個標誌合起來就行了。 
Pattern.COMMENTS(?x)     在這種模式下,匹配時會忽略 ( 正則表示式裡的 ) 空格字元 ( 譯者注:不是指表示式裡的 "\\s" ,而是指表示式裡的空格, tab ,回車之類 ) 。註釋從 # 開始,一直到這行結束。可以通過嵌入式的標誌來啟用 Unix 行模式。

Pattern.DOTALL(?s)     在這種模式下,表示式 '.' 可以匹配任意字元,包括表示一行的結束符。預設情況下,表示式 '.' 不匹配行的結束符。 
Pattern.MULTILINE
(?m)     在這種模式下, '^' 和 '$' 分別匹配一行的開始和結束。此外, '^' 仍然匹配字串的開始, '$' 也匹配字串的結束。預設情況下,這兩個表示式僅僅匹配字串的開始和結束。 
Pattern.UNICODE_CASE
(?u)     在這個模式下,如果你還啟用了 CASE_INSENSITIVE 標誌,那麼它會對 Unicode 字元進行大小寫不明感的匹配。預設情況下,大小寫不敏感的匹配只適用於 US-ASCII 字符集。 
Pattern.UNIX_LINES(?d)     在這個模式下,只有 '\n' 才被認作一行的中止,並且與 '.' , '^' ,以及 '$' 進行匹配。

拋開空泛的概念,下面寫出幾個簡單的 Java 正則用例: 

◆ 比如,在字串包含驗證時 

// 查詢以 Java 開頭 , 任意結尾的字串 
  Pattern pattern = Pattern.compile("^Java.*");
  Matcher matcher = pattern.matcher("Java 不是人 ");
  boolean b= matcher.matches();
  // 當條件滿足時,將返回 true ,否則返回 false
  System.out.println(b);

◆ 以多條件分割字串時 
Pattern pattern = Pattern.compile("[, |]+");
String[] strs = pattern.split("Java Hello World  Java,Hello,,World|Sun");
for (int i=0;i<strs.length;i++) {
    System.out.println(strs[i]);


◆ 文字替換(首次出現字元) 
Pattern pattern = Pattern.compile(" 正則表示式 ");
Matcher matcher = pattern.matcher(" 正則表示式 Hello World, 正則表示式 Hello World");
// 替換第一個符合正則的資料 
System.out.println(matcher.replaceFirst("Java"));

◆ 文字替換(全部) 
Pattern pattern = Pattern.compile(" 正則表示式 ");
Matcher matcher = pattern.matcher(" 正則表示式 Hello World, 正則表示式 Hello World");
// 替換第一個符合正則的資料 
System.out.println(matcher.replaceAll("Java"));


◆ 文字替換(置換字元) 
Pattern pattern = Pattern.compile(" 正則表示式 ");
Matcher matcher = pattern.matcher(" 正則表示式 Hello World, 正則表示式 Hello World ");
StringBuffer sbr = new StringBuffer();
while (matcher.find()) {
    matcher.appendReplacement(sbr, "Java");
}
matcher.appendTail(sbr);
System.out.println(sbr.toString());

◆ 驗證是否為郵箱地址 

String str="[email protected]";
Pattern pattern = Pattern.compile("[\\w\\.\\-][email protected]([\\w\\-]+\\.)+[\\w\\-]+",Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(str);
System.out.println(matcher.matches());

◆ 去除 html 標記 
Pattern pattern = Pattern.compile("<.+?>", Pattern.DOTALL);
Matcher matcher = pattern.matcher("<a href=\"index.html\"> 主頁 </a>");
String string = matcher.replaceAll("");
System.out.println(string);

◆ 查詢 html 中對應條件字串 
Pattern pattern = Pattern.compile("href=\"(.+?)\"");
Matcher matcher = pattern.matcher("<a href=\"index.html\"> 主頁 </a>");
if(matcher.find())
  System.out.println(matcher.group(1));
}

◆ 擷取 http:// 地址 
// 擷取 url
Pattern pattern = Pattern.compile("(http://|https://){1}[\\w\\.\\-/:]+");
Matcher matcher = pattern.matcher("dsdsds<http://dsds//gfgffdfd>fdf");
StringBuffer buffer = new StringBuffer();
while(matcher.find()){              
    buffer.append(matcher.group());        
    buffer.append("\r\n");              
System.out.println(buffer.toString());
}
        
◆ 替換指定 {} 中文字 

String str = "Java 目前的發展史是由 {0} 年 -{1} 年 ";
String[][] object={new String[]{"\\{0\\}","1995"},new String[]{"\\{1\\}","2007"}};
System.out.println(replace(str,object));

public static String replace(final String sourceString,Object[] object) {
            String temp=sourceString;    
            for(int i=0;i<object.length;i++){
                      String[] result=(String[])object[i];
               Pattern    pattern = Pattern.compile(result[0]);
               Matcher matcher = pattern.matcher(temp);
               temp=matcher.replaceAll(result[1]);
            }
            return temp;
}


◆ 以正則條件查詢指定目錄下檔案 

 // 用於快取檔案列表 
        private ArrayList files = new ArrayList();
        // 用於承載檔案路徑 
        private String _path;
        // 用於承載未合併的正則公式 
        private String _regexp;
        
        class MyFileFilter implements FileFilter {

              /**
               * 匹配檔名稱 
               */
              public boolean accept(File file) {
                try {
                  Pattern pattern = Pattern.compile(_regexp);
                  Matcher match = pattern.matcher(file.getName());                
                  return match.matches();
                } catch (Exception e) {
                  return true;
                }
              }
            }
        
        /**
         * 解析輸入流 
         * @param inpu

檢視原文:http://shukuiyan.iteye.com/blog/1058672