使用java正則表達式的正確姿勢

使用java正則表達式的正確姿勢

一、用途

  1. 用於字符串處理
    • 字符串匹配
    • 字符串查找
    • 字符串替換
  2. 例子
    • IP地址是否正確
    • 從網頁中揪出email地址
    • 從網頁中揪出鏈接等
  3. 使用的類
    • java.lang.String
    • java.util.regex.Pattern
    • java.util.regex.Matcher

二、. * + ? 表示什麼意思?

  1. *表示是一個字符
  2. X*表示X出現0個或多個
  3. X+表示出現1個或多個
  4. X?表示X出現0個或1個
  5. X{n}表示X出現n次
  6. X{n,}X最少出現n次,最多出現次數不限制
  7. X{n,m}X出現至少n次,不超過m次
  8. {}表示對字符出現次數的限制
  9. [-]表示限制字符範圍
    10.[a-z]表示字符範圍只能是a-z

示例代碼:

        //初步認識. * + ? {} []
        p("a".matches("."));//true
        p("aa".matches("aa"));//true
        p("aaaa".matches("a*"));//true
        p("aaaa".matches("a+"));//true
        p("".matches("a*"));//true
        p("aaaa".matches("a?"));//false
        p("".matches("a?"));//true
        p("a".matches("a?"));//true
        p("21234567898".matches("\\d{3,100}"));//true
        p("192.168.0.aaa".matches("\\d(1,3)\\.\\d(1,3)\\.\\d(1,3)\\.\\d(1,3)"));//false
        p("192".matches("[0-2][0-9][0-9]"));//true

private static void p(Object o){
        System.out.println(o);
    }

三、[]表示什麼意思?(控制範圍)

  1. []表示匹配[]內其中一個字符
  2. ^表示取反
  3. -表示範圍
  4. |表示或者 &&表示並且
    示例代碼:
 public static void main(String[] args) {
        //範圍
        p("a".matches("[abc]"));//匹配abc其中的一個字符 true
        p("a".matches("^abc"));//匹配abc之外的字符 false

        //匹配a-z或者A-Z之間的字符 3種寫法
        p("A".matches("[a-zA-Z]"));//true
        p("A".matches("[a-z]|[A-Z]"));//true
        p("A".matches("[a-z[A-Z]]"));//true

        p("R".matches("[A-Z&&[RFG]]"));//A-Z之間並且是RFG三者之一 true

    }

    private static void p(Object o){
        System.out.println(o);
    }

四、常用的"\字母"表示什麼意思?

  1. \d表示0-9之間的數字 [0-9]
  2. \D表示除0-9之外的字符 [^0-9]
  3. \s表示一個空白字符[ \t\n\x0b\f\r] 包含空格tab鍵等
  4. \S表示不包含空白字符[^\s]
  5. \w表示包含構成英文單詞的字符[a-zA-Z_0-9]
  6. \W表示不包含英文單詞的字符[^\w]

示例:

 		 //認識\s \w \d \
        p(" \n\r\t".matches("\\s{4}"));//true
        p(" ".matches("\\S"));//false
        p("a_0".matches("\\w{3}"));//true
        p("abc888&^%".matches("[a-z]{1,3}\\d+[&^%]+"));//true
        p("\\".matches("\\\\"));// java比較反斜槓 true

private static void p(Object o){
        System.out.println(o);
    }

五、邊界

^ 表示起始位置
$ 表示結束位置
\b表示一個單詞的邊界(邊界指的是空格、換行、空白字符、tab鍵等)

示例:

 		//邊界
        p("hello sir".matches("^h.*"));//h開頭後面跟0個或者多個字符 true
        p("hello sir".matches(".*ir$"));//ir結尾前面有0個或者多個字符 true
        p("hello sir".matches("^h[a-z]{1,3}o\\b.*"));//h開頭,o後面是否包含單詞邊界 true
        p("hellosir".matches("^h[a-z]{1,3}o\\b.*"));//h開頭,o後面是否包含單詞邊界 false

 private static void p(Object o){
        System.out.println(o);
    }

六、matches、find、lookingAt

matches匹配整個字符串
find找子串
lookAt從開始位置找

示例代碼:

 		Pattern p = Pattern.compile("\\d{3,5}");//全部爲數字,長度爲3-5
        String s = "123-23234-234-00";
        Matcher m = p.matcher(s);
        p(m.matches());//false
        m.reset();//matches和find一起使用會出現問題,一般要加reset,否則輸出結果會有出入

         //find 依次查找子串
        p(m.find());//true
        //輸出找到子串以後的開始位置和結束位置(前提是必須能找到這子串,否則會報錯)
        p(m.start() + "-" + m.end());//輸出0-3
        p(m.find());//true
        p(m.start() + "-" + m.end());//輸出4-9
        p(m.find());//true
        p(m.start() + "-" + m.end());//輸出10-13
        p(m.find());//false

        //lookingAt從開始位置找,每次從開頭開始找
        p(m.lookingAt());//true
        p(m.lookingAt());//true
        p(m.lookingAt());//true
        p(m.lookingAt());//true

    }

    private static void p(Object o){
        System.out.println(o);
    }

七、replacement字符串替換

示例代碼:

        //字符串替換replacement
        Pattern pattern = Pattern.compile("java",Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher("java JAVA JAva JaVa JAvA iloveJava you hate java");
        //把字符串中所有的java(忽略大小寫),全部替換成大寫的JAVA
        p(matcher.replaceAll("JAVA"));
        
        private static void p(Object o){
        System.out.println(o);
    }

輸出結果如下:
輸出結果
示例代碼2:

 //字符串替換replacement
        Pattern pattern = Pattern.compile("java",Pattern.CASE_INSENSITIVE);//忽略大小寫
        Matcher matcher = pattern.matcher("java JAVA JAva JaVa JAvA iloveJava you hate java the end");
        //要求把找到的第一個java字符串編程大寫,找到的第二個變成小寫,依次類推
        StringBuffer buffer = new StringBuffer();
        int i = 0;
        while (matcher.find()){
            i++;
            if(i % 2 == 0){
                matcher.appendReplacement(buffer,"java");
            }else {
                matcher.appendReplacement(buffer,"JAVA");
            }
        }
        matcher.appendTail(buffer);//加上尾巴
        p(buffer);
    }

    private static void p(Object o){
        System.out.println(o);
    }

輸出結果:
輸出結果

八、group分組

如何判斷是第幾組,數小括號就行
作用:抓取字符串中的部分內容

示例代碼:

 		//分組
        Pattern pattern = Pattern.compile("(\\d{3,5})([a-z]{2})");//匹配3-5位的數字,兩個字母
        String s = "123aa-345345bb-234cc-00";
        Matcher matcher = pattern.matcher(s);
        while (matcher.find()){
            //只輸出3-5位的數字也就是第一組
            p(matcher.group(1));
            //只輸出兩位字母也就是第二組
           // p(matcher.group(2));
           
           private static void p(Object o){
        	System.out.println(o);
    		}

輸出結果:
輸出結果
如果group傳入的是2,則輸出如下:
輸出結果
如果group什麼都不傳,則輸出結果如下:
輸出結果

九、讀取本地網頁中的email地址

示例代碼:

public class EmailSpider {
    public static void main(String[] args) {
        try {
            BufferedReader br = new BufferedReader(new FileReader("E:\\留下你的電子郵箱地址,我們來寫Email吧。.html"));
            String line = "";
            while ((line = br.readLine()) != null){
                //判斷有沒有讀到結尾
                parse(line);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void parse(String line) {
        Pattern pattern = Pattern.compile("^\\s*\\w+(?:\\.{0,1}[\\w-]+)*@[a-zA-Z0-9]+(?:[-.][a-zA-Z0-9]+)*\\.[a-zA-Z]+\\s*$");
        Matcher matcher = pattern.matcher(line);
        while (matcher.find()){
            System.out.println(matcher.group());
        }
    }

}

十、其他知識

向前引用:

示例代碼:

//向前引用
        Pattern pattern = Pattern.compile("(\\d\\d)\\1");
        // \\1指的是後面找到的結果必須和第一個組捕捉的字符串一樣
        String s = "1214";//false
//        String s = "1212";//true
        Matcher matcher = pattern.matcher(s);
        System.out.println(matcher.matches());

忽略大小寫或者其他規則可以用下面這種寫法:

		//忽略大小寫
		//第一種寫法
        Pattern pattern = Pattern.compile("java",Pattern.CASE_INSENSITIVE);
        //第二種寫法
        p("java".matches("(?i)(java)"));

十一、有待補充 qulifiers (greedy reluctant possessive的區別)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章