正则表达式

正则表达式基本知识


  • 基本语法
  • 高级语法
  • 练习
  • editplus,notpad++,ultraedit,eclipse中使用正则表达式

正则表达式(Regular Expression)简介


  • 为什么需要使用正则表达式?
    • 文本的复杂处理。
  • 正则表达式的优势和用途
    • 一种强大而灵活的文本处理工具。
    • 大部分编程语言、数据库、文本编辑器、开发环境都支持正则表达式。
  • 正则表达式定义
    • 正如他的名字一样是描述一种规则,通过这个规则可以匹配一类字符串。
    • 学习正则表达式很大程度上就是学习正则表达式的语法规则。
  • 开发中使用正则表示的流程
    • 分析所要匹配的数据,写出测试用的典型数据。
    • 在工具软件中进行匹配测试。
    • 在程序中调用通过测试的正则表达式。

正则表达式基本语法


  • 普通字符

    • 字母、数字、汉字、下划线、以及没有特殊定义的标点符号,都是“普通字符”。表达式中的普通字符,在匹配一个字符串的时候,匹配与之相同的一个字符。
  • 简单转义字符

    \n 代表换行符
    \t 制表符
    \ 代表\本身
    ^,$,.,{,},?,+,*,|,[,] 匹配这些字符创本身
  • 标准字符集合:

    • 能够与“多种字符”匹配的表达式

    • 主义区分大小写,大写是相反的意思。

      \d 任意一个数字,0-9中的任意一个。
      \w 任意一个字母或数字或下划线,也就是A-Z,a-z,0-9,_中任意一个。
      \s 包括空格、制表符、换行符等空白字符的其中任意一个。
      . 小数点可以匹配任意一个字符(除了换行符)
      如果要匹配在”\n”在内的所有字符,一般用[\s\S]。
      [\s\S] 匹配包含“\n”在内所有字符串
  • 自定义字符集合

    • []方括号匹配方式,能够匹配方括号中任意一个字符.

    • [ab5@]:匹配”a”或”b”或”5”或”@”。

    • [^abc]:匹配”a”,”b”,”c”之外的任意一个字符。

    • [f-k]|:匹配日”f”-“k”之间的任意一个字符。

    • [^A-f0-3]:匹配”A”-“F”,”0”-“3’之外的任意一个字符。

    • 正则表达式的特殊符号,被包含到中括号中,则失去特殊意义,除了^,-之外。

    • 标准字符集合,处理小数点之外,如果被包含于中括号,自定义字符集合将包含该集合。

      • [\d.-+]讲匹配数组,小数点 + -
  • 量词(Quantifier)

    • 修饰匹配次数的特殊符号

      {n} 表达重复n次
      {m,n} 表达至少重复m次,最多重复n次
      {m,} 表达至少重复m次
      ? 匹配表达式0次或1次,相当于{0,1}
      + 表达式至少出现1线,相当{1,}
      * 表达式不会出现或出现任意次,{0,}
    • 匹配次数中的贪婪模式(匹配字符越多越好,默认!)。

    • 匹配次数中的非贪婪模式(匹配字符越少越好,修饰匹配次数的特殊符号后再加上一个”?”号)。

  • 字符边界

    • (本组编辑匹配的不是字符而是位置,符合某种条件的位置)()

      ^ 与字符串开始的位置匹配
      $ 与字符串结束的地方配置
      \b 匹配一个当前的边界
    • \b匹配这样一个位置,前面的字符和后面的字符不全是\w

  • 选择符和分组

    表达式 作用
    ` `分支结构
    ()捕获组 (1)在被修饰匹配次数的时候,括号中的表达式可以作为整体被修饰
    (2)取得匹配结果的时候,括号中的表达式匹配到的内容可以被单独得到
    (3)每个括号会分配一个编号,使用()的捕获根据左括号的顺序从1开始自动编号。捕获元素编号为0的第一个捕获是由整个正则表达式模式
    匹配的文本
    非捕获组(?:Exception)(?:([a-z]{2})) 一些表达式中,不得不使用(),但又不需要保存()中子表达式匹配的内容,这时候可以使用非捕获组来抵消使用()带来的副作用。
  • 反向引用(\nnn):

    • 每一个()都会分配一个编号,使用()的捕获根据左括号的顺序从1开始自动编导。
    • 通过反向作用,可以对分组已捕获的字符串进行引用。

正则表达式的匹配模式

  • INGORECASE 忽略大小写模式
    • 匹配时忽略大小写。
    • 默认情况下,正则表达式是要区分大小写的。
  • SIGNLELINE 单行模式
    • 整个文本看做是一个字符串,只有一个开头,一个结尾。
    • 使小数点“.”可以匹配包含“\n”在内的任意字符。
  • MULTILINE 多行模式
    • 每行都是一个字符串,都有开头和结尾。
    • 在指定了MULTILINE之后,如果需要仅匹配字符串开始和结束位置,可以使用\A和\Z

预搜索(零宽断言)(环视)

  • 占有字符还是零宽度,是针对匹配的内容是否保存到最终的匹配结果中而言的。
  • 零宽断言的几种方式
    • (?=exp):断言自身出现的位置的后面能匹配表达式exp。
    • (?<=exp>):断言自身出现的位置的前面能匹配表达式exp。
    • (?!exp):断言此位置的后面不能匹配exp。
    • (?<!exp>):断言此位置的前面不能匹配表达式exp。

正则表达式的应用

  • 电话号码的应用

    • 电话号码有数字和”-“构成。

    • 电话号码为7到8位。

    • 如果电话号码中包含有取号,那么区号为三位或四位,首位为0。

    • 区号用”-“和其它部分隔开。

    • 移动电话号码为11位

    • 11位一定电话号码的第一位和第二位为”13“、”15“、”18“

    • 结果:(0\d{2,3}-\d{7,9})|(1[35789]\d{9})

  • 电子邮件的地址验证

    • 用户名:字母,数字,下划线,中划线组成

    • @

    • 网址:字母、数字组成

    • 小数点 .

    • 组织域名:2-4字母组成

    • 不区分大小写

    • 结果 [\w-]+@[a-z0-9A-Z]+(.[A-Za-z]{2,3}){1,2}


Java程序中使用正则表达式

  • 相关类位于:java.util.regex包下面
  • 类pattern:
    • 正则表达式的编译表示形式。
    • Pattern p=Pattern.compile(r,int);//建立正则表达式,并启动响应模式
  • 类matcher:
    • 通过解释Pattern对character sequence执行匹配操作的引擎。
    • Matcher m=p.matcher(str);//匹配str字符串

Java模拟编程的原理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package regular;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/***
* 网络爬虫取连接
* @author 1huangzewei
*
*/
public class webSpiderTest {
//获得urlStr网页的源代码
public static String getURLContent(String urlStr) {
StringBuilder sb=new StringBuilder();
try {
URL url=new URL(urlStr);

BufferedReader reader=new BufferedReader(new InputStreamReader(url.openStream()));
String temp="";
while((temp=reader.readLine())!=null) {
sb.append(temp);
}

} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return sb.toString();
}
public static List<String> getMatcher(String destStr,String regex) {
List<String> result=new ArrayList<String>();
//Pattern p=Pattern.compile("<a[\\s\\S]+?</a>");//找到超链接
Pattern p = Pattern.compile(regex);//找到a href;
Matcher m = p.matcher(destStr);
while (m.find()) {
result.add(m.group(1));
}
return result;
}
public static void main(String[] args) {
String destStr=getURLContent("http://163.com");
//List<String> list=getMatcher(destStr,"href=\"([\\s\\S]+?)\"");
//List<String> list=getMatcher(destStr,"(<img+[\\S\\s]+?)>");
List<String> list=getMatcher(destStr,"data-original=\"([\\s\\S]+?)\"");
for(String temp:list) {
System.out.println(temp);
}
}
}