閱讀700 返回首頁    go 技術社區[雲棲]


馬士兵 正則表達式的學習(上)

天氣預報係統六天的麵向對象的寫法已經完成,代碼也比較完善了。下一個任務就是獲取7,8,9三天的天氣情況,數據源來自https://www.haotq.com/d_anqing.html。


中國天氣網的信息由於有JSON接口,所以直接用JSON解析即可,這個新數據源隻能采用寫個爬蟲,抓取網頁,進行解析才行。由於我需要的數據信息鎖在DIV之中,所以我打算使用正則表達式進行解析,現在需要做的是好好學習一下正則表達式。


01正則表達式簡介:


一個點對應一個字母:

package com.zzk.cn;

public class Test {
    public static void main(String[] args) {
    	//簡單認識正則表達式的概念
    	System.out.println("abc".matches("..."));//一個點對應一個字母,字符匹配
    	
    	
    }
}

輸出:

true


02初步認識正則表達式


所有的字母替換成  -

匹配字符


package com.zzk.cn;

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

public class Test {
    /**
     * @param args
     */
    public static void main(String[] args) {
    	//簡單認識正則表達式的概念
    	p("abc".matches("..."));//一個點對應一個字母,字符匹配           true
    	
    	p("a8729a".replaceAll("\\d", "-"));//所有的數字替換成一條橫線  a----a
    	// \d代表一列數組,敲1一個反斜杠是不對的,在java裏,1個反斜杠和後麵的是轉義字符,\d再加一個\,兩個反斜杠代表一個反斜杠
    	
    	Pattern p=Pattern.compile("[a-z]{3}");
    	Matcher m=p.matcher("fgh");//去匹配一個字符串   true
    	p(m.matches());//true
    	p("fgh".matches("[a-z]{3}"));//true
    	p("fgha".matches("[a-z]{3}"));//false
    	p("f".matches("[a-z]"));//匹配一個字符 true
    	p("fgha".matches("[a-z]"));//false,隻是匹配一個字符
    	p("fg4".matches("[a-z]{3}"));//false
    }
    
    
    public static void p(Object o) {
    	System.out.println(o);
    }
}


03_認識MetaCharacters


認識. * +

package com.zzk.cn;

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

public class Test {
    /**
     * @param args
     */
    public static void main(String[] args) {
    	//初步認識. * +
    	p("a".matches("."));//true
    	
    	p("aa".matches("aa"));//true
    	p("aaaa".matches("a*"));//true a 零次或多次
    	p("aaaa".matches("a+"));//true a 一次或多次
    	
    	p("".matches("a?"));//true 一次或一次也沒有
    	p("aaaa".matches("a?"));//false
    	p("a".matches("a?"));//true
    	
    	p("214523145234532".matches("\\d{3,100}"));//true 至少出現3次,不超過100次
    	p("192.168.0.101".matches("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}"));//true \\.代表. 1到3位的數字 最簡單的檢驗IP地址的方法、可能有不對的
    	p("192".matches("[0-2][0-9][0-9]"));//true
    	
    	
    }
    
    
    public static void p(Object o) {
    	System.out.println(o);
    }
}


04 範圍

package com.zzk.cn;

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

public class Test {
    /**
     * @param args
     */
    public static void main(String[] args) {
   	
    	//熟悉範圍
    	p("a".matches("[aaa]"));//true a、b 或 c(簡單類) 匹配一個字符
    	p("a".matches("[^abc]"));//false  任何字符,除了 a、b 或 c(否定)
    	p("A".matches("[a-zA-z]"));//true a 到 z 或 A 到 Z,兩頭的字母包括在內(範圍)
    	
    	p("A".matches("[a-z]|[A-z]"));//true
    	p("A".matches("[a-z[A-z]]"));//true  和上麵意思差不多 a 到 d 或 m 到 p:[a-dm-p](並集)
    	
    	p("R".matches("[A-Z&&[RFG]]"));//true  A-Z之中的並且是RFG三者之一的  [a-z&&[def]] d、e 或 f(交集) 
    	
    	
    }
    
    
    public static void p(Object o) {
    	System.out.println(o);
    }
}


05.其他MetaCharacters


認識\s \w \d \

package com.zzk.cn;

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

public class Test {
    /**
     * @param args
     */
    public static void main(String[] args) {
   	
    	//認識\s \w \d \
    	p(" \n\r\t".matches("\\s{4}"));//代表4個空白字符
    	p(" ".matches("\\S"));//false \\S非空白字符
    	p("a_8".matches("\\w{3}"));//true  單詞字符:[a-zA-Z_0-9]
    	p("abc888&^%".matches("[a-z]{1,3}\\d+[&^#%]+"));//true a-z出現1-3次 \\d+數字出現一次或者多次  [&^#%]+代表&^#%這四種符號出現一次或者多次
        p("\\".matches("\\\\"));//true 正則表達式裏匹配一個反斜線需要2個反斜線表示
    }
    
    
    public static void p(Object o) {
    	System.out.println(o);
    }
}


06

POSIX STYLE 

邊界匹配 開頭和結尾

空白行

小練習

package com.zzk.cn;

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

public class Test {
    /**
     * @param args
     */
    public static void main(String[] args) {
   	
    	//POSIX Style
    	p("a".matches("\\p{Lower}"));//true 小寫字母字符:[a-z]
    	
    	//邊界匹配 開頭和結尾
    	p("hello sir".matches("^h.*"));// true一行的開頭 .代表一個字符 *代表後麵跟著0個或多個字符
    	p("hello sir".matches(".*ir$));//true  以ir結尾,前麵帶有0個或多個字符
    	p("hello sir".matches("^h[a-z]{1,3}o\\b.*"));//true以h開頭 ,a-z出現1-3次 一個o 後麵緊跟一個單詞邊界\\b
    	p("hellosir".matches("^h[a-z]{1,3}o\\b.*"));//false 無單詞邊界
    	
    	//空白行
    	p(" \n".matches("^[\\s&&[^\\n]]*\\n{1}quot;)); //true
    	//空格 換行符            不是   開頭是一個空白字符並且不是換行符 結束是換行符 並且結束是這行的末尾 
    	
    	//練習
    	p("aaa 8888c".matches(".*\\d{4}."));//true .* 0個或者多個字母  \\d{4}後麵跟著四位數字        .四位數字後還有一個字母
        p("aaa 8888c".matches(".*\\b\\d{4}."));//true    .*0個或者多個字母  \\b單詞邊界 \\d{4}後麵跟著四位數字 四位數字後還有一個字母
        p("aaa8888c".matches(".*\\d{4}."));//true     .*0個或者多個字母    \\d{4}後麵跟著四位數字    .後麵還有1個字母
        p("aaa8888c".matches(".*\\b\\d{4}."));//false .*0個或者多個字母 \\b單詞邊界 \\d{4}後麵跟著四位數字 四位數字後麵還有1個字母 錯誤 沒有單詞邊界!
    }
    
    
    public static void p(Object o) {
    	System.out.println(o);
    }
}


07 email正則匹配

package com.zzk.cn;

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

public class Test {
    /**
     * @param args
     */
    public static void main(String[] args) {
   	
    	//email地址匹配
    	p("asdfasdfsafsf@dsdfsdf.com".matches("[\\w[.-]]+@[\\w[.-]]+\\.[\\w]+"));
    	//構成單詞的字符,或者是.或者是-   +代表出現一次或多次    @符號  單詞字符      後麵跟著.號                         跟著單詞字符 +代表出現一次或者多次
    }
    
    
    public static void p(Object o) {
    	System.out.println(o);
    }
}


08 matches find lookingat


package com.zzk.cn;

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

public class Test {
    /**
     * @param args
     */
    public static void main(String[] args) {
   	
    	Pattern p=Pattern.compile("\\d{3,5}");//數字出現3次到5次
    	String s="123-34345-234-00";
    	Matcher m=p.matcher(s);
    	p(m.matches());//false matches永遠匹配整個字符串                不匹配     字符串超過5位
    	
    	m.reset();
    	p(m.find());//找一個和這個模式一樣的淄川,找到則輸出true,用完find 刪除字串,重新再找         123 true

    	p(m.find());//34345 true

    	p(m.find());//234   true
    
    	p(m.find());//00 false

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


RESET的作用是吐出吃進的字符串

對比DEMO如下:

package com.zzk.cn;

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

public class Test {
    /**
     * @param args
     */
    public static void main(String[] args) {
   	
    	Pattern p=Pattern.compile("\\d{3,5}");//數字出現3次到5次
    	String s="123-34345-234-00";
    	Matcher m=p.matcher(s);

    	
    	//m.reset();   m.reset的作用是吃掉的字符吐出來
    	p(m.find());//true     123- 全部吃進

    	p(m.find());//true     34345-全部吃進    

    	p(m.find());//false    234-全部吃進
    
    	p(m.find());//false     00  

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

輸出:

true
true
true
false


第二個DEMO如下:

package com.zzk.cn;

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

public class Test {
    /**
     * @param args
     */
    public static void main(String[] args) {
   	
    	Pattern p=Pattern.compile("\\d{3,5}");//數字出現3次到5次
    	String s="123-34345-234-00";
    	Matcher m=p.matcher(s);
    	p(m.matches());//false matches永遠匹配整個字符串                不匹配     字符串超過5位         吃進123-
    	
    	//m.reset();   m.reset的作用是吃掉的字符吐出來
    	p(m.find());//true     34345-全部吃進

    	p(m.find());//true     234-全部吃進    

    	p(m.find());//false    00 報錯
    
    	p(m.find());//false      報錯

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

輸出;

false
true
true
false
false


package com.zzk.cn;

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

public class Test {
    /**
     * @param args
     */
    public static void main(String[] args) {
   	
    	Pattern p=Pattern.compile("\\d{3,5}");//數字出現3次到5次
    	String s="123-34345-234-00";
    	Matcher m=p.matcher(s);
    	p(m.matches());//false matches永遠匹配整個字符串                不匹配     字符串超過5位         吃進123-
    	
    	//m.reset();   m.reset的作用是吃掉的字符吐出來
    	p(m.find());//true     34345-全部吃進

    	p(m.find());//true     234-全部吃進    

    	p(m.find());//false    00 報錯
    
    	p(m.find());//false      報錯

    	p(m.lookingAt());//每次從頭開始找       true
    	p(m.lookingAt());                       //true
    	p(m.lookingAt());                       //true
    	p(m.lookingAt());                       //true
    }
    
    
    public static void p(Object o) {
    	System.out.println(o);
    }
}

輸出:

false
true
true
false
false
true
true
true
true


09 start_end

package com.zzk.cn;

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

public class Test {
    /**
     * @param args
     */
    public static void main(String[] args) {
   	
    	Pattern p=Pattern.compile("\\d{3,5}");//數字出現3次到5次
    	String s="123-34345-234-00";
    	Matcher m=p.matcher(s);
    	p(m.matches());//false matches永遠匹配整個字符串                不匹配     字符串超過5位         吃進123-
    	
    	m.reset();   //m.reset的作用是吃掉的字符吐出來
    	p(m.find());//true     123
    	p(m.start() + "-" + m.end());//從第0位到第3位 end是找到字符的後一個位置
    	p(m.find());//true         
    	p(m.start() + "-" + m.end());//  34345 4到9位
    	p(m.find());//true
    	p(m.start() + "-" + m.end());// 234 11到13位
    	p(m.find());//false      報錯
      	p(m.lookingAt());//每次從頭開始找
    	p(m.lookingAt());
    	p(m.lookingAt());
    	p(m.lookingAt());
    }
    
    
    public static void p(Object o) {
    	System.out.println(o);
    }
}

輸出:

false
true
0-3
true
4-9
true
10-13
false
true
true
true
true


總結:matches永遠匹配整個字符串 ,find找子串,lookingat每次從頭開始找.start是開始的字符串位置(從0,1,2……開始計數),end是結束字符串的後一位位置。








最後更新:2017-04-02 06:52:14

  上一篇:go Excel模板導出(針對複雜報表的一種解決方式)
  下一篇:go RandomAccessFile類實現隨機讀寫文件