马士兵 正则表达式的学习(上)

来源:互联网 发布:c语言得知电脑时间 编辑:程序博客网 时间:2024/06/06 02:50

天气预报系统六天的面向对象的写法已经完成,代码也比较完善了。下一个任务就是获取7,8,9三天的天气情况,数据源来自http://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是结束字符串的后一位位置。