正则表达式

一、基本语法

  • 简单的转义符
\n 换行
\t Tab
\\ 代表\
\^, \$, \., \+ 等等 代表\后面的字符本身,^ $, 因为这些字符本身有其他含义,所以要在前面加转义符

 

  • 标准字符
\d 0-9中任意一个数字
\w     任意一个字母或数字或下划线
\s 任意一个空格,制表符,换行符
. 小数点可以匹配任一字符,除了换行符。想要包括换行符,可以用[\s\S], \S是匹配除了空白符的其他所有字符

   

  -  注意区分大小写,大写表示相反的意思。 例如 \s 和 \S 

 

 

  • 自定义字符集合,用[]表示,例如上面的[\s\S],表示的就是匹配括号内的内容。
[ab5@] 匹配"a"或"b"或“5”或"@"
[^abc] 表示取相反,比如[^abc],表示匹配除abc以外的其他字母
[f-k]  匹配"f" - "k" 之间的任意一个字母
[^A-F0-3]  匹配"A"~"F", "0"~"3"之外的任意一个字符

   - 注意:特殊字符在[ ] 里面失去其本身意义,比如 + - .这些符号。

 

 

  • 量词 (Quantifier)
{n} 表达式重复n次,ex: \d{6}, 匹配任意6个数字
{m, n} 表达式至少重复m次,最多重复n次
{m, } 表达式最少重复m次
? 匹配表达式0次或者1次,相当于{0, 1}
+ 表达式至少出现1次,相当于{1, }
* 表达式不出现或出现任意次,相当于(0,}

 

    - 非贪婪模式,匹配越少越好,在表达式后面加个?号,例如:\d{3, 6}? , 尽量往3次匹配

 

  • 字符边界(匹配的不是字符而是位置 ,符合某种条件的位置)

 

^ 于字符串开始的地方匹配
$ 于字符串结束的地方匹配
\b 匹配一个单词边界, 这个位置前面的字符和后面的字符不全是\w
  • 分支结构,捕获组/非捕获组,反向引用

    分支结构: |    表示或

    捕获组:()

    非捕获组 (?:Expression) :匹配到括号里的内容,但引用不到了,不会存下来,可以节省内存

    反向引用:\n 

    ex: 怎么匹配到gogo, toto, dodo. ([a-z]{2})/1,([a-z]{2})是一个捕获组,代表匹配到两个字符,这个就匹配到了go,后面的反向引用:\1 ,指的是重复前面捕获组里面的内容一次,所以可以匹配到gogo

 

 

  • 预搜索(零宽断言)
(?=exp) 断言自身出现的位置的后面能匹配表达式exp
(?<=exp) 断言自身出现的位置的前面能匹配表达式exp
(?!exp) 断言此位置的后面不能匹配表达式exp
(?<!exp) 断言此位置的前面不能匹配表达式exp

 

    ex: 匹配所有以ing结尾的单词(doing, eating, going) 

      [a-z] +(?=ing)   *注意:这个式子的匹配结果是doing,后面的 " ing " 不会被选中,因为在原表达式里的ing,是一个语法表达式,不是直接匹配

 

 

二、正则表达式练习 

  

1、 电话号码验证

  • 电话号码由数字和 " - " 构成
  • 电话号码为7到8位
  • 如果电话号码中包含区号,区号为3位或者4位,首位是0
  • 区号用 " - " 和其他部分隔开
  • 移动电话号码为11位
  • 11位移动电话号码的第一位和第二位为 "13", "15", "18
//先考虑匹配固话 xxx(x)-xxxxxxx

0\d{2,3}-\d{7,9} // 0 + 两到三位的数字 + - + 7到9位的数字

//手机号
1[35789]\d{9}

//用括号和 | 连接
(0\d{2,3}-\d{7,9})|(1[35789]\d{9})

 

2、电子邮箱验证

[\w\-]+@[a-zA-Z0-9]+(\.[A-Za-z]{2, 4}){1,2}

 

 

三、正则表达式在Java中的使用

 

import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 正则表达式在java中的使用
 */
public class Demo1 {
    public static void main(String[] args) {
        //表达式对象
        Pattern p1 = Pattern.compile("\\w+"); //java里面正则要多一个右斜杠,切记
        Pattern p2 = Pattern.compile("([a-z]+)([0-9])+");//匹配a-z字母和0-9数字,注意这个表达式有两段
        //创建Matcher对象
        Matcher m = p2.matcher("aa22###sxz531###zcx312");
        //matches方法,返回一个布尔值,这里会返回false,因为有符号 #
        Boolean Rst1 = m.matches();

        //find方法,group方法。find会一次一次找下一个能匹配的子序列,group可以返回每一个子序列
        while (m.find()){
            System.out.println(m.group());
            System.out.println(m.group(1));
            System.out.println(m.group(2));
        }

        //替换
        String str1 = m.replaceAll("&");
        System.out.println(str1);

        //分割,正则可以切割复杂的边界,而不仅仅依赖一个分割符(例如逗号)
        String strAAA = "a3234b31231c321";
        String[] strBBB = strAAA.split("\\d+"); //那数字分割。输出[a, b, c]
        System.out.println(Arrays.toString(strBBB));
    }
}

 

 

四、正则手写网络爬虫

 

/**
 * 正则表达式,手写网络爬虫
 */
public class Demo1 {

    //创建获得网页源码内容的方法
    public static String getURLContent(String urlStr, String charSet){
        StringBuilder sb = new StringBuilder();
        try {
            URL url = new URL(urlStr);
            BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream(), Charset.forName(charSet)));
            String temp ="";
            while ((temp=br.readLine())!=null){
                sb.append(temp);
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sb.toString();
    }

    public static List<String> getHyperlink(String desStr, String regexStr){
        //利用正则表达式,寻找网页中的超链接
        Pattern p = Pattern.compile(regexStr);
        Matcher m = p.matcher(desStr);
        List<String> result = new ArrayList<String>();
        while (m.find()){
            result.add(m.group(1));
        }
        return result;
    }

    public static void main(String[] args) {
        String desStr = getURLContent("http://www.163.com", "gbk");

        //Pattern p = Pattern.compile("<a[\\s\\S]+?</a>"); //在java中,\s要变\\s             //取到超链接的整个内容
        List<String> result = getHyperlink(desStr,"href=\"([\\w\\s./:]+?)\"");     //只取超链接的有效地址

        for (String temp : result){
            System.out.println(temp);
        }
    }
}

 

posted on 2018-10-09 15:24  TheExile  阅读(158)  评论(0)    收藏  举报

导航