亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Java > 正文

Java的正則表達式深入分析

2019-11-26 16:10:32
字體:
來源:轉載
供稿:網友

一.regex(正則表達式):RegularExpressions(代替了StringTokenizer);字符串處理利器;在unix流行,perl使用regex更牛。
主要用在字符串匹配、查找和替換。例如:匹配IP(范圍小于256)使用正則很好搞;從網頁中揪出大量email地址發送垃圾郵件;從網頁里揪出鏈接。包含Matcher(用模式匹配字符串后產生的結果)和pattern。

復制代碼 代碼如下:

 /*
          * 告知此字符串是否匹配給定的正則表達式(也是一個字符串)。
          */
         System.out.println("abc".matches("..."));//每個"."表示一個字符


復制代碼 代碼如下:

 /*
          * 把字符串里的所有數字替換成"-",普通方法需要charAt逐個判斷;
          * "http://d"表示任意一個數字或者換成"[0-9]";
          * "http://D"表示任意一個非數字或者換成"[^0-9]"
          */
         System.out.println("ab54564654sbg48746bshj".replaceAll("[0-9]", "-"));//每個"."表示一個字符

二、
復制代碼 代碼如下:

/*
          * compile將給定的正則表達式編譯到模式中(每次編譯需要費時間);{3}表示恰好三次。
          *     X{n} X,恰好 n 次
          *    X{n,} X,至少 n 次
          *    X{n,m} X,至少 n 次,但是不超過 m 次
          */
         Pattern p = Pattern.compile("[a-z]{3}");
         Matcher m = p.matcher("ggs");//創建匹配給定輸入與此模式的匹配器。內部實際上是創建了一個優先狀態的自動機(編譯原理)
         //matcher和matches里待匹配的字符串實際上是CharSequence(接口),不過String實現了該接口,存在多態
         System.out.println(m.matches());//若是"ggss"就不匹配了
         //可一直接"ggs".matches("[a-z]{3}"),不過上面的有好處,至少效率高了,而且Pattern和Matcher提供了很多功能

三、在regex“. * +”中叫Meta Character;ctrl + shift + "/"表示注釋,換成"/"表示去掉注釋。
復制代碼 代碼如下:

"a".matches(".");//true,"."表示任意一個字符,漢字也行
         "aa".matches("aa");//true,也就是說普通字符串也可以作為正則表達式
         /*
          * true,"*"表示0或者多個字符,不過后面的要和第一個相同,
          * 否則false,也就是判斷字符串是否是單一字符組成的字符串
          */
         "aaaa".matches("a*");
         "".matches("a*");//true
         "aaa".matches("a?");//true,一次或者0次
         "".matches("a?");//true
         "a".matches("a?");//true
         "544848154564113".matches("http://d{3,100}");//true
         //這個是最簡單的IP判斷,不過若是超過255則判斷不出來
         "192.168.0.aaa".matches("http://d{1,3}//.//d{1,3}//.//d{1,3}//d{1,3}");
         "192".matches("[0-2][0-9][0-9]");

四、[abc]表示匹配任意一個字符;[^abc]表示出了abc以外的其他字母(必須還是字母,若是空串也返回false)字符;[a-zA-Z]等價于"[a-z]|[A-Z]"是否是某個大小寫字母;[A-Z&&[ABS]]表示大寫字母中取ABS中任一個。
復制代碼 代碼如下:

//發現|和||沒區別,&和&&有區別,不知道這么理解對不對
         System.out.println("C".matches("[A-Z&&[ABS]]"));//false
         System.out.println("C".matches("[A-Z&[ABS]]"));//true
         System.out.println("A".matches("[A-Z&&[ABS]]"));//true
         System.out.println("A".matches("[A-Z&[ABS]]"));//true
         System.out.println("C".matches("[A-Z|[ABS]]"));//true
         System.out.println("C".matches("[A-Z||[ABS]]"));//true

五、/w 單詞字符:[a-zA-Z_0-9] 進行用戶名匹配時;/s 空白字符:[ /t/n/x0B/f/r]; /S 非空白字符:[^/s] ;/W 非單詞字符:[^/w] 。
復制代碼 代碼如下:

" /n/t/r".matches("http://s{4}");//true
         " ".matches("http://S");//false
         "a_8".matches("http://w{3}");//true
         //“+”表示一次或者多次
         "abc888&^%".matches("[a-z]{1,3}//d+[&^#%]+");//true
         /*
          * 待匹配字符也只是一個反斜線,不過不可寫成"/"那么和后面的"組合了,
          * 前面的"無法匹配就會CE。
          * 后面不可寫成"http://",那么會運行錯誤(編譯沒問題),必須寫成"http:////"
          */
         System.out.println("http://".matches("http:////"));//true

六、POSIX 字符類(僅 US-ASCII)
復制代碼 代碼如下:

 /p{Lower} 小寫字母字符:[a-z] ;/p{Upper} 大寫字母字符:[A-Z] ;/p{ASCII} 所有 ASCII:[/x00-/x7F] ;/p{Alpha} 字母字符:[/p{Lower}/p{Upper}] ;/p{Digit} 十進制數字:[0-9] 。

七、邊界匹配器
^ 行的開頭
  $ 行的結尾
  /b 單詞邊界
  /B 非單詞邊界
  /A 輸入的開頭
  /G 上一個匹配的結尾
  /Z 輸入的結尾,僅用于最后的結束符(如果有的話)
  /z 輸入的結尾
復制代碼 代碼如下:

"hello world".matches("^h.*");//^行的開頭
         "hello world".matches(".*ld$");//$行的結尾
         "hello world".matches("^h[a-z]{1,3}o//b.*");///b單詞邊界
         "helloworld".matches("^h[a-z]{1,3}o//b.*");

 " /n".matches("^[//s&&[^//n]]*//n$");//判斷空白行,空白行開頭是空白符


八、還可以在find方法下使用m.start()和m.end()返回開始位置和結束位置的下一個;若是找不到則出錯。
復制代碼 代碼如下:

Pattern p = Pattern.compile("http://d{3,5}");
         String s = "133-34444-333-00";
         Matcher m = p.matcher(s);
         m.matches();//matches匹配全部字符串
         m.reset();
         /*
          * 下面若是先調用了reset方法則輸出true,true,true,false.
          * 否則倒數第二個find也輸出false。
          * 原因如下:
          * matches匹配到第一個"-"發現不匹配了,但是這四個字符已經被吃掉啦,再次匹配就從
          * 34444開始了,第二個find從333,因為find匹配的是下一個子序列。
          * reset方法讓matches吃掉的字符串再吐出來。
          * 綜上:matches和find之間要使用reset,因為二者相互影響
          *
          */
         m.find();
         m.find();
         m.find();//嘗試查找與該模式匹配的輸入序列的下一個子序列
         m.find();
         /*
          * 嘗試將從區域開頭開始的輸入序列與該模式匹配。
          * Thinking in java的作者狠狠滴批評了這個方法,因為從字面看不出來到底從哪開始匹配。
          * 下面全部是true,因為每次都從頭開始
          */
         m.lookingAt();
         m.lookingAt();
         m.lookingAt();
         m.lookingAt();

九、字符串替換
復制代碼 代碼如下:

import java.util.regex.Matcher;
 import java.util.regex.Pattern;

 public class TestRegexReplacement {

     public static void main(String[] args) {

         Pattern p = Pattern.compile("java",Pattern.CASE_INSENSITIVE);//后面的參數是整形,表示“大小寫不敏感”
         Matcher m = p.matcher("Java java hxsyl Ilovejava java JaVaAcmer");
         while(m.find()) {
             System.out.println(m.group());//m.group會輸出所有的java(忽略大小寫)

         }

        
         String s = m.replaceAll("Java");//String也有該方法
         System.out.println(s);

         m.reset();//一定要加,因為find和matcher相互影響
         StringBuffer sb = new StringBuffer();
         int i = 0;
         /*
          * 下面的方法是把找到的奇數個java替換為“Java”,偶數個替換成"java"
          */
         while(m.find()) {
             i++;
             //不能直接寫成i&1必須轉化為boolean
             if((i&1)==1) {
                 m.appendReplacement(sb, "Java");
             }else {
                 m.appendReplacement(sb, "java");
             }
         }

         m.appendTail(sb);//把找到的最后一個java后邊的剩余字符串加上
         System.out.println(sb);//不加reset的話只輸出了Acmer
     }
 }

十、分組
復制代碼 代碼如下:

/*
          * 分別加上小括號,不算最外邊的大括號,第一個左括號便是第一組
          */
         Pattern p = Pattern.compile("(//d{3,5})([a-z]{2})");
         String s = "123aaa-77878bb-646dd-00";
         Matcher m = p.matcher(s);
         while(m.find()) {
             System.out.println(m.group());
             System.out.println(m.group(1));//輸出每對符合的 數字
             System.out.println(m.group(2));//輸出每對符合的 字母
         }

十一、抓取網頁中的email
復制代碼 代碼如下:

import java.io.BufferedReader;
 import java.io.FileNotFoundException;
 import java.io.FileReader;
 import java.io.IOException;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;

 /*
  * 需要什么養的方法的話先些方法名
  * 然后ctrl + 1列出推薦,系統創建該方法
  */
 public class EmailSpider {

     public static void main(String[] args) {
         // TODO Auto-generated method stub
         try {
             BufferedReader br = new BufferedReader(new FileReader("F://regex.html"));
             String line = "";
             try {
                 while((line=br.readLine())!=null) {
                     solve(line);
                 }
             } catch (IOException e) {
                 // TODO Auto-generated catch block
                 e.printStackTrace();
             }

         } catch (FileNotFoundException e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
         }

 
     }

     private static void solve(String line) {
         // TODO Auto-generated method stub
         //正則表達式要是不滿足相應功能的話不會出錯,因為他是字符串
         Pattern p = Pattern.compile("[//w[.-]]+@[//w[.-]]+//.[//w]+");
         Matcher m = p.matcher(line);

         while(m.find()) {
             System.out.println(m.group());
         }

     }

 }

十二、代碼統計
復制代碼 代碼如下:

View Code
 /*
  * 統計代碼里多少空行,注釋行,程序行
  * 實際上使用String里的startsWith和endsWith也行.
  * 若是項目經理用的話還要統計每行的字符數是否以{;結尾,防止偷懶
  */
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FileReader;
 import java.io.IOException;

 public class CoderCount {

     static long normalLines = 0;
     static long commentLines = 0;
     static long whiteLines = 0;

     public static void main(String[] args) {
         File f = new File("D://share//src");
         File[] codeFiles = f.listFiles();
         for(File child : codeFiles){
             if(child.getName().matches(".*//.java$")) {
                 solve(child);
             }
         }

         System.out.println("normalLines:" + normalLines);
         System.out.println("commentLines:" + commentLines);
         System.out.println("whiteLines:" + whiteLines);

     }

     private static void solve(File f) {
         BufferedReader br = null;
         boolean comment = false;
         try {
             br = new BufferedReader(new FileReader(f));
             String line = "";
             while((line = br.readLine()) != null) {
                 /*
                  * //有的注釋行前面有一個tab
                  * 不可寫在readLine后
                  * 最后一行的話會空指針
                  */
                 line = line.trim();
                 //readLine讀出字符串后就把后面的換行去掉啦
                 if(line.matches("^[//s&&[^//n]]*$")) {
                     whiteLines ++;
                 } else if (line.startsWith("/*") && !line.endsWith("*/")) {
                     commentLines ++;
                     comment = true;   
                 } else if (line.startsWith("/*") && line.endsWith("*/")) {
                     commentLines ++;
                 } else if (true == comment) {
                     commentLines ++;
                     if(line.endsWith("*/")) {
                         comment = false;
                     }
                 } else if (line.startsWith("http://")) {
                     commentLines ++;
                 } else {
                     normalLines ++;
                 }
             }
         } catch (FileNotFoundException e) {
             e.printStackTrace();
         } catch (IOException e) {
             e.printStackTrace();
         } finally {
             if(br != null) {
                 try {
                     br.close();
                     br = null;
                 } catch (IOException e) {
                     e.printStackTrace();
                 }
             }
         }
     }

 }

十三、Quantifiers
包括?*+;默認全是Greedy,還有Reluctant和Possessive(獨占性的)。
復制代碼 代碼如下:

//加上分組是為了看得更清晰一些
     Pattern p = Pattern.compile("(.{3,10})+[0-9]");
     String s = "aaaa5bbbb6";//長度是10
     Matcher m = p.matcher(s);
     /*
      * 現在輸出0-10,默認是Greedy,先吞進10個字符,發現不匹配,吐出來一個,發現匹配了;
      * 若是Pattern.compile("(.{3,10}?)+[0-9]")則成了Reluctant,那么是先吞進三個字符,發現不匹配,繼續吞入 知道匹配,輸出0到5;
      * 若是Pattern.compile("(.{3,10}++)+[0-9]")則是Possessive(獨占式),也是先吞入10個字符,但是不向外吐,那么就不匹配了,
      * 這種方式主要用在需要高效率的地方(會有誤差)。
      */
     if(m.find()) {
         System.out.println(m.start() + "----" + m.end());
     }else {
         System.put.println("Not match!");
     }

十四、補充(非捕獲組)
復制代碼 代碼如下:

//非捕獲組的意思和字面相反,意思是若是符合則捕獲
     Pattern p = Pattern.compile("(?=a).{3}");
     /*
      * 輸出a66,相當于要求以a開頭,也可以這么寫Pattern.compile("[a].{2}");
      * 若是Pattern.compile(".{3}(?!=a)")不是不以a結尾{2}[^a],而是下一個字符不是a(lookahead),輸出44a,66b,所以這種用法不常用;
      * 若是Pattern.compile(".{3}(?=a)")則輸出444(因為?=a是lookahead),放在前面則包含在組內,后面則不包含在組內;
      *
      *
      */
     String s = "444a66b";
     Matcher m = p.matcher(s);
     while(m.find()) {
         System.out.println(m.group());
     }

十五、Back Reference
復制代碼 代碼如下:

Pattern p = Pattern.compile("(//d//d)//1");
     /*
      * 輸出true,//1表示和第一個組的一樣,若改成1213就不對了;
      * 若是Pattern.compile("(//d(//d))//2")則需改成122才對
      *
      */
     String s = "1212";
     Matcher m = p.matcher(s);
     System.out.println(m.matches());

十六、flags的簡寫
"."是不匹配換行的,記住CASE_INSENSITIVE就行了,簡寫“通過嵌入式標志表達式  (?i) 也可以啟用不區分大小寫的匹配”。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
色先锋资源久久综合5566| 91精品国产91久久| 国产91精品久久久久久| 亚洲人成电影网站色www| 亚洲夜晚福利在线观看| 日韩经典一区二区三区| 国产999在线观看| 欧美激情综合色综合啪啪五月| 色香阁99久久精品久久久| 亚洲第一av在线| 欧美裸体视频网站| 热久久免费国产视频| 亚洲日韩欧美视频| 欧美日韩中文字幕日韩欧美| 国内精品久久久久久影视8| 黑人极品videos精品欧美裸| www.日韩.com| 91成人在线观看国产| 久久99国产精品自在自在app| 欧美激情伊人电影| 欧美亚洲免费电影| 亚洲欧洲xxxx| 久久久久久这里只有精品| 91精品在线影院| 91久久国产精品| 欧美三级欧美成人高清www| 精品亚洲夜色av98在线观看| 亚洲字幕一区二区| 欧美激情在线一区| 日韩在线观看免费网站| 在线观看不卡av| 欧美精品在线看| 亚洲自拍偷拍一区| 欧美自拍视频在线| 国产精品女视频| 成人欧美一区二区三区黑人孕妇| 国产在线观看不卡| 国产亚洲精品久久| 亚洲最新中文字幕| 欧美二区乱c黑人| 国产精品中文久久久久久久| 日本一区二区在线播放| 国产色婷婷国产综合在线理论片a| 成人网在线观看| 国产一区二区三区直播精品电影| 久久精品国产91精品亚洲| 92裸体在线视频网站| 久久久黄色av| 欧美日韩亚洲视频| 欧美国产日韩一区二区| 欧美激情在线观看视频| 黑人巨大精品欧美一区二区| 一本久久综合亚洲鲁鲁| 国产在线拍偷自揄拍精品| 亚洲综合在线做性| 成人性生交xxxxx网站| 欧美国产第二页| 国产精品一区二区3区| 亚洲天堂成人在线视频| 日韩中文在线视频| 欧美高清第一页| 97精品视频在线观看| 日韩激情片免费| 色在人av网站天堂精品| 成人精品视频99在线观看免费| 欧美激情中文字幕乱码免费| 国产精品久久99久久| 日韩精品www| 亚洲偷熟乱区亚洲香蕉av| 精品亚洲一区二区三区四区五区| 国产精品女主播| www.久久草.com| 国产欧美日韩免费| 亚洲视频网站在线观看| 欧美在线视频免费| 日韩精品极品在线观看播放免费视频| 国产精品美女免费看| 精品国产一区二区在线| 97在线观看视频| 久久艳片www.17c.com| 欧美日韩国产一区中文午夜| 日韩av一区二区在线观看| 精品中文字幕久久久久久| 最近2019中文免费高清视频观看www99| 亚洲色图15p| 国产日韩精品综合网站| 欧美激情精品久久久久久免费印度| 亚洲欧美日韩中文在线制服| 日韩高清有码在线| 欧美成人性色生活仑片| 亚洲精品国产免费| 精品美女永久免费视频| 国产成人精品视频在线| 91成人福利在线| 91老司机精品视频| 国产日韩av高清| 欧洲成人在线观看| 国产精品一区二区三| 亚洲色图日韩av| 欧美极品少妇xxxxⅹ喷水| 久久韩剧网电视剧| 亚洲国产日韩欧美在线动漫| www.欧美精品| 日韩中文在线中文网三级| 亚洲国内精品视频| 国产精品福利网| 欧美精品videosex牲欧美| 欧美激情一区二区三区久久久| 91久久久亚洲精品| 亚洲国产精品成人va在线观看| 秋霞av国产精品一区| 亚洲天堂网在线观看| 亚洲成年人在线播放| 国产精品91在线| 91成人精品网站| 欧美日韩福利视频| 欧美一区深夜视频| 精品久久久中文| 久久男人资源视频| 欧美黄色片免费观看| 欧美第一黄网免费网站| 午夜精品久久17c| 欧美性猛交xxxx乱大交蜜桃| 欧美不卡视频一区发布| 国产成人精品久久| 国产久一一精品| 亚洲美女性视频| 日韩电影大片中文字幕| 亚洲国产精品系列| 久操成人在线视频| 91久久夜色精品国产网站| 欧美激情精品久久久久久久变态| 久久精品视频99| 欧美日韩国产在线看| 懂色av中文一区二区三区天美| 亚洲bt欧美bt日本bt| 国产精品永久免费观看| 成人黄色影片在线| 欧美日韩美女在线观看| 97免费在线视频| 全亚洲最色的网站在线观看| 国产一区二区精品丝袜| 国产精品视频一| 欧美极品美女电影一区| 日本一欧美一欧美一亚洲视频| 成人精品视频99在线观看免费| 欧美性猛交xxxx乱大交极品| 亚洲图片制服诱惑| 国产精品综合久久久| 日韩视频免费观看| 国产一区二区三区视频免费| 国产精品视频26uuu| 成人高清视频观看www| 欧美成人免费全部| 国产精品第七十二页| 97涩涩爰在线观看亚洲| 伦伦影院午夜日韩欧美限制| 91精品久久久久久久久久另类| 亚州成人av在线| 亚洲欧美一区二区三区四区| 91美女片黄在线观看游戏| 久久久国产精品x99av| 亚洲激情 国产| 国产91网红主播在线观看|