1. 程式人生 > >利用java正則表示式來解析並獲取指定的字串

利用java正則表示式來解析並獲取指定的字串

Java的正則表示式不僅可以用來匹配驗證字串是否符合標準型別,還可以用來解析字串,獲取自己想要得到的資料。在java.util.regex包下提供了系列的類來對字串進行匹配。來看一下下面的例子:

public static String parse (String s)

{

  Pattern pattern =Pattern.compile("charset=(.+?)\"");//匹配的模式

    //萬用字元中也要加入轉移字元 (.+?)代表要查詢的內容

    Matcher matcher=pattern.matcher(s);

    while(matcher.find())

    {

       System.out.println(matcher.group(1)); //每次返回第一個即可 可用groupcount()方法來檢視捕獲的組數 個數

    }

    return s;

}

要匹配一下型別的字串:

<meta http-equiv="Content-Type"content="text/html; charset=UTF-8">

其中標紅的部分為想要獲取的資料,注意這裡要獲取的資料長度不固定,並且可能為unicode

Gb2312等其他編碼型別,在這裡我們所希望獲取的是其編碼方式。

具體應用例項:

package URL;

import java.net.*;

import java.util.regex.Matcher;

import java.util.regex.Pattern;

import java.io.BufferedReader;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.util.regex.*;

public class DataFromURL {

public static String parse (String s)

{

    Pattern pattern =Pattern.compile("charset=(.+?)\""

);

    //萬用字元中也要加入轉移字元 (.+?)代表要查詢的內容

    Matcher matcher=pattern.matcher(s);

    while(matcher.find())

    {

       System.out.println(matcher.group(1));

    }

    return s;

}

public static  voidgetDataFromURL(String url)

{

    try{

    URL u=new URL(url);//通過連線建立URL物件

    BufferedReader reader=new BufferedReader(new InputStreamReader(u.openStream(),"gb2312"));//採用gb2312方式開啟輸入流

    int c;

    /*while((c=reader.read())!=-1)//該方法為每個字元讀取

    {

       System.out.print((char)c);

    }*/

    String s;

    while((s=reader.readLine())!=null)//不為空一次性讀取一行

    {

       //System.out.println(s);

       if(s.contains("charset"))

       {

           parse(s);

       }

    }

    }catch(Exception e)

    {

       e.printStackTrace();

    }

}

}

附錄正則表示式說明:


 眾所周知,在程式開發中,難免會遇到需要匹配、查詢、替換、判斷字串的情況發生,而這些情況有時又比較複雜,如果用純編碼方式解決,往往會浪費程式設計師的時間及精力。因此,學習及使用正則表示式,便成了解決這一矛盾的主要手段。大 家都知道,正則表示式是一種可以用於模式匹配和替換的規範,一個正則表示式就是由普通的字元(例如字元a到z)以及特殊字元(元字元)組成的文字模式,它 用以描述在查詢文字主體時待匹配的一個或多個字串。正則表示式作為一個模板,將某個字元模式與所搜尋的字串進行匹配。自從jdk1.4推出java.util.regex包,就為我們提供了很好的JAVA正則表示式應用平臺。
 因為正則表示式是一個很龐雜的體系,所以我僅例舉些入門的概念,更多的請參閱相關書籍及自行摸索。 

//
反斜槓
/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
前一個匹配的結束

^
為限制開頭
^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
「()」中規定一個組合型別比如,我查詢<ahref=/"index.html/">index</a>中<a href></a>間的資料,可寫作<a.*href=/".*/">(.+?)</a>在使用Pattern.compile函式時,可以加入控制正則表示式的匹配行為的引數:
PatternPattern.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開頭,任意結尾的字串
  Patternpattern = Pattern.compile("^Java.*");

  Matchermatcher = 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 (inti=0;i<strs.length;i++) {
   System.out.println(strs[i]);


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


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



◆文字替換(置換字元)
Pattern pattern =Pattern.compile("
正則表示式");
Matcher matcher =pattern.matcher("
正則表示式 HelloWorld,正則表示式 Hello World ");
StringBuffer sbr =new StringBuffer();

while(matcher.find()) {
   matcher.appendReplacement(sbr, "Java");
}
matcher.appendTail(sbr);
System.out.println(sbr.toString());

◆驗證是否為郵箱地址

Stringstr="[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"},newString[]{"//{1//}","2007"}};

System.out.println(replace(str,object));

public staticString replace(final String sourceString,Object[] object) {
           Stringtemp=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 {
                 Patternpattern = Pattern.compile(_regexp);
                 Matchermatch = pattern.matcher(file.getName());               
                 returnmatch.matches();
               } catch (Exception e) {
                 returntrue;
               }
             }
           }
       
       /**
        * 解析輸入流
        * @param inputs

        */
       FilesAnalyze (String path,String regexp){
           getFileName(path,regexp);
       }
       
       /**
        * 分析檔名並加入files
        * @param input

        */
       private void getFileName(String path,String regexp) {
           //目錄
             _path=path;

             _regexp=regexp;
             File directory = new File(_path);
             File[] filesFile =directory.listFiles(new MyFileFilter());
             if (filesFile == null) return;
             for (int j = 0; j <filesFile.length; j++) {
              files.add(filesFile[j]);
             }
             return;
           }
    
       /**
        * 顯示輸出資訊
        * @param out

        */
       public void print (PrintStream out) {
           Iterator elements = files.iterator();
           while (elements.hasNext()) {
               File file=(File)elements.next();
                  out.println(file.getPath());    
           }
       }

       public static void output(String path,String regexp) {

           FilesAnalyze fileGroup1 = newFilesAnalyze(path,regexp);
           fileGroup1.print(System.out);
       }
    
       public static void main (String[] args) {
          output("C://","[A-z|.]*");
       }

Java正則的功用還有很多,事實上只要是字元處理,就沒有正則做不到的事情存在。(當然,正則解釋時較耗時間就是了|||……)