Java 正則中的(.*?)vs(.*)

  1. public static void main(String[] args) {  
  2.   
  3.         //選擇最小和最大重複次數  
  4.         String a="{user=\"administrator\",password=\"root\"}";  
  5.         String b="user   =\"a\"";//注意=號之間有空格  
  6.         String c="user\r\n=\"c\"";//注意有換行符號  
  7.           
  8.         //獲取雙引號之間的內容,分別獲得a,b,c中的所有的用戶的名稱  
  9.         String regex="(?s)user.*?=(\".*?\")";  
  10.         match(regex,a);//user="administrator"  
  11.         match(regex,b);//user   ="a"  
  12.         match(regex,c);//user  
  13.                        //="c"  
  14.           
  15.         //上面的非常簡單,注意以下事例  
  16.         //選擇最小和最大重複數  
  17.         //注意以下幾點,user =這個之間可能有空格  
  18.         //我們需要的結果是找出user='xxx'的信息,其餘不要  
  19.         String notice="[{user='admin',password='admin'}," +  
  20.                        "{user='yhc',password='yhc'}]";  
  21.         //也許大家會覺得.*?爲什麼需要?號,那麼一下我們看看  
  22.         //有?和沒有?的區別  
  23.         String regex1="user.*='(.*?)'";//user.*=之間沒有?  
  24.         match(regex1, notice);  
  25.         //輸出結果(錯誤):user='admin',password='admin'},{user='yhc',password='yhc'  
  26.           
  27.         String regex2="user.*?='(.*?)'";//user.*=之間有?  
  28.         match(regex2, notice);  
  29.         //輸出結果(正確):  
  30.         //user='admin'  
  31.         //user='yhc'  
  32.           
  33.         //爲什麼上面就因爲一個?號而有這麼大的區別咧?  
  34.         //解釋以上代碼運行機制  
  35.         //有了匹配文本中的第一個user之後,引擎就會到達(.*),其中點號(.)可以  
  36.         //匹配任意字符,其中包括換行符,星號(*)則把它重複0次或更多次,請注意,  
  37.         //這裏的星號(*)是貪心的,因此點星(.*)會匹配直到目標文件結束的所有的  
  38.         //內容,注意=====>>>>(.*)會吃了所有的目標文件內容,從第一個匹配  
  39.         //user的地方開始;  
  40.           
  41.         //當(.*)把肚子吃飽之後,引擎纔會試圖去匹配在目標文本末尾的=  
  42.         //這個表達式,當然,一定會匹配失敗,但這並不會代表此次匹配就結束了,  
  43.         //正則引擎會進行回溯backtrack,當匹配某一個位置之後  
  44.         //,正則表達式都會保存一個回溯位置,如果正則表達式匹配之後的文本失敗後  
  45.         //那麼正則引擎還可以回到這些位置  
  46.         //當=匹配匹配失敗之後,引擎進行回溯,讓(.*)放棄它的匹配中的一個  
  47.         //字符接着=會被再次嘗試匹配,這次在文本中的最後一個字符的位置,  
  48.         //如果依然失敗的話,那麼引擎會再一次進行回溯在文件的倒數第2個字符出嘗試匹配  
  49.         //這個過程會一直繼續,直到=匹配成功位置,如果一直沒有匹配成功,那麼最終(.*)  
  50.         //會用完所有的回溯位置,然後正則匹配失敗  
  51.           
  52.         //如果在整個回溯的過程中=在某個點匹配成功,那麼就會接着嘗試匹配'如果'匹配  
  53.         //失敗,引擎接着進行回溯,這個過程會一直重複,直到='(.*?)'可以被匹配爲止  
  54.           
  55.         //問題就出現在.*上,因爲星號是貪心的,所以你們要注意哦!  
  56.         //我們需要使用lazy 懶惰 可以在後面放一個?使其變爲懶惰  
  57.         //例如:(*?),(+?),(??) ,{1,100}? 都可以將其變爲懶惰   
  58.           
  59.     }  
  60.       
  61.     public static void match(String regex,String input){  
  62.             //創建正則對象  
  63.             Pattern pattern=Pattern.compile(regex);  
  64.             //匹配對象  
  65.             Matcher matcher=pattern.matcher(input);  
  66.             //輸出匹配字符串  
  67.             while(matcher.find()){  
  68.                 System.out.println(matcher.group());  
  69.             }  
  70.     }  

如果以上有寫錯誤的地方,請大家指出,thanks!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章