JAVA学习——正则表达式实例源码



JAVA学习正则表达式。

正则表达式:主要应用于操作字符串,通过一些特定的符号来体现

举例:

QQ号的校验

6~9位,0不得开头,必须是数字

String类中有matches方法

matches(String regex)
告知此字符串是否匹配给定的正则表达式

regex,就是给定的正则表达式

 

  1. public static void checkQQ() {
  2.         //第一位是数字1-9,第二位以后是0-9,除去第一位数剩下数字位数范围是5到8位
  3.         String regex = ”[1-9][0-9]{5,8}”;//正则表达式
  4.         String qq = ”123459″;
  5.         boolean flag = qq.matches(regex);
  6.         System.out.println(qq+” : ”+flag);
  7.     }

 

 

PS:正则表达式虽然简化了书写,但是代码的阅读性极差

符号意义

正则表达式难就难在符号太多。

 

预定义字符类
. 任何字符(与行结束符可能匹配也可能不匹配)
\d 数字:[0-9]
\D 非数字: [^0-9]
\s 空白字符:[ \t\n\x0B\f\r]
\S 非空白字符:[^\s]
\w 单词字符:[a-zA-Z_0-9]
\W 非单词字符:[^\w]
字符类
[abc] ab 或 c(简单类)
[^abc] 任何字符,除了 ab 或c(否定)
[a-zA-Z] a 到 z 或 A 到 Z,两头的字母包括在内(范围)
[a-d[m-p]] a 到 d 或 m 到 p[a-dm-p](并集)
[a-z&&[def]] de 或 f(交集)
[a-z&&[^bc]] a 到 z,除了 b 和 c[ad-z](减去)
[a-z&&[^m-p]] a 到 z,而非 m 到 p[a-lq-z](减去)

 

 

边界匹配器
^ 行的开头
$ 行的结尾
\b 单词边界
\B 非单词边界
\A 输入的开头
\G 上一个匹配的结尾
\Z 输入的结尾,仅用于最后的结束符(如果有的话)
\z 输入的结尾
Greedy 数量词
X? X,一次或一次也没有
X* X,零次或多次
X+ X,一次或多次
X{n} X,恰好 n 次
X{n,} X,至少 n 次
X{n,m} X,至少 n 次,但是不超过m 次

 

Logical 运算符
XY X 后跟 Y
X|Y X 或 Y
(X) X,作为捕获组

 

Back 引用
\n 任何匹配的 nth捕获组

 

 

  1. public static void check() {
  2. <span style=”white-space:pre”>        </span>
  3.      String string = ”aoooooz”;
  4.      String regex = ”ao{4,}z”;//正则表达式
  5.      boolean flag = string.matches(regex);
  6.      System.out.println(string+” : ”+flag);
  7. }

常见功能

 

1.匹配 2.切割 3.替换 4.获取

匹配:用的是String类中的matches方法

 

  1. public static void check() {
  2.     //匹配手机号码是否正确
  3.     String tel = ”18753377511″;
  4.     //第一位是1,第二位是3或5或8
  5.     //String regex = ”1[358][0-9]{9}”;
  6.     String regex = ”1[358]\\d{9}”;
  7.     //字符串中\,代表转义,所以再加上一个”\”将”\”转义
  8.     boolean flag = tel.matches(regex);
  9.     System.out.println(tel+” : ”+flag);
  10. }

 

 

切割:就是以前用的String类中的split(String regex)方法,以前用的是” “,空格一般的非特殊符号,都可看作规则

空格

 

  1. public static void check() {
  2.         //以空格为分割,切割,空格可能出现多次
  3.         String str = ”a   b  c     d e f”;
  4.         String regex = ” +”;//空格出现1次或者多次
  5.         String[] line = str.split(regex);
  6.         for(String i : line){
  7.             System.out.println(i);
  8.         }
  9.     }

点,PS:点本身在正则表达式中是特殊符合

  1. String str = ”a.b.c.d.e..f”;
  2.         String regex = ”\\.+”;//\.转义后还是.,所以再加一个\
  3.         String[] line = str.split(regex);

以叠词为分割

 

正则用()来封装成组

所以叠词就可以表示为,.代表任意字符,(.)封装成组,(.)\\1,代表余下都和第一组相同

 

  1. String str = ”a@@@b####c…dtttef”;
  2.         String regex = ”(.)\\1+”;//
  3.         String[] line = str.split(regex);

组:((A)(B(C))),共有几组,哪几组

 


以左括号数,

((A)(B(C))) 1

(A)    2

(B(C))      3

(C)         4

无括号就是第0组


替换:

replaceAll(String regex,String replacement)
使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。

replaceFirst(String regex,String replacement)
使用给定的 replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。

 

  1. public static void check() {
  2.         //把叠词变为一个字符
  3.         String str = ”abgggggcffffdggggs”;
  4.         String regex = ”(.)\\1+”;//
  5.         str = str.replaceAll(regex, ”$1″);
  6.         System.out.println(str);
  7.     }

PS:美元符号在其他参数中,可以对前一个参数中的已有的正则规则的获取

 

 

  1. public static void check() {
  2.     //18753377511 -> 187****7511
  3.     String str = ”18753377511″;
  4.     String regex = ”(\\d{3})\\d{4}(\\d{4})”;
  5.     System.out.println(str);
  6.     str = str.replaceAll(regex, ”$1****$2″);
  7.     System.out.println(str);
  8. }

获取

 

正则本身就是一个对象

Pattern类

指定为字符串的正则表达式必须首先被编译为此类的实例。然后,可将得到的模式用于创建Matcher 对象,依照正则表达式,该对象可以与任意字符序列匹配。执行匹配所涉及的所有状态都驻留在匹配器中,所以多个匹配器可以共享同一模式。

//将正则的规则进行对象的封装
//Pattern p = Pattern.compile(“a*b”);
//通过正则对象的matcher方法字符串相关联,获取对字符串操作的匹配器对象Matcer
//Matcher m = p.matcher(“aaaab”);
//通过Matcher匹配器对象的方法对字符串进行操作
//boolean b = m.matches();

Matcher类

 

  • matches 方法尝试将整个输入序列与该模式匹配。
  • lookingAt 尝试将输入序列从头开始与该模式匹配。
  • find 方法扫描输入序列以查找与该模式匹配的下一个子序列。
  1. public static void check() {
  2.         String str = ”ni hao,wohao,ta ye hao”;
  3.         String regex = ”\\b[a-z]{3}\\b”;//\\b :单词边界
  4.         Pattern p = Pattern.compile(regex);
  5.         Matcher m = p.matcher(str);
  6.         while(m.find())//想要获取,就要先找,有没有,有才能获取
  7.         {
  8.             System.out.println(m.group());
  9.             System.out.println(m.start()+” : ”+m.end());//获取起始下标
  10.         }
  11.     }

练习:

 

将aaa…aa..aaa…bbb…b…bbb…ccc…ccc 变为 abcd

 

  1. public static void test() {
  2.         String str = ”aaa…aa..aaa…bbb…b…bbb…ccc…ccc”;
  3.         System.out.println(str);
  4.         String regex = ”\\.+”;
  5.         str = str.replaceAll(regex, ”");//去点
  6.         regex = ”(.)\\1+”;
  7.         str = str.replaceAll(regex, ”$1″);//去叠词
  8.         System.out.println(str);
  9.     }

排序IP地址

 

 

  1. public static void test() {
  2. //      String str = ”192.0.0.1    127.0.0.24  3.3.3.5    150.15.3.41″;
  3. //      System.out.println(“ip : ”+str);
  4. //      String regex = ” +”;
  5. //      String[] strs = str.split(regex);
  6. //
  7. //      TreeSet<String> ts = new TreeSet<String>();//自动排序
  8. //      for(String s : strs){
  9. //          ts.add(s);
  10. //      }
  11. //      for(String s : ts){//这样排,是按照字符串排序
  12. //          System.out.println(s);
  13. //      }
  14.         //所以在每个ip的每段数字,就用两个0补全
  15.         String str = ”192.0.0.1    127.0.0.24  3.3.3.5    150.15.3.41″;
  16.         String regex = ”(\\d+)”;
  17.         str = str.replaceAll(regex, ”00$1″);
  18.         System.out.println(“补0 : ”+str);
  19.         regex = ”0*(\\d{3})”;
  20.         str = str.replaceAll(regex, ”$1″);
  21.         System.out.println(“保留3位 : ”+str);
  22.         regex = ” +”;
  23.         String[] strs = str.split(regex);
  24.         TreeSet<String> ts = new TreeSet<String>();//自动排序
  25.         for(String s : strs){
  26.             ts.add(s);
  27.         }
  28.         for(String s : ts){
  29.             System.out.println(s.replaceAll(“0*(\\d+)”, ”$1″));
  30.         }
  31.     }

邮箱地址的简单校验

 

 

  1. public static void test() {
  2.         String mail = ”aa_a@163.com.cn”;
  3.         String regex = ”\\w+@\\w+(\\.[a-zA-Z]{2,3})+”;//+代表一次或多次
  4.         boolean flag = mail.matches(regex);
  5.         System.out.println(mail+” : ”+flag);
  6.     }

注意:开发时,正则阅读性差,会不断验证,然后封装起来

 

 

练习:网页爬虫:一个程序用于在互联网中获取符合指定规则的数据

爬取邮箱地址。

 

  1. public class asd {
  2.     public static void main(String[] args) throws Exception {
  3.         //List<String> list = getmail();//本地
  4.         List<String> list =  getweb();//网络
  5.         for(String i : list){
  6.             System.out.println(i);
  7.         }
  8.     }
  9.     public static List<String> getweb() throws Exception{
  10.         //URL url = new URL(“http://192.168.0.1:8080/myweb/mymail.html”);
  11.         URL url = new URL(“http://news.baidu.com/”);
  12.         BufferedReader brin = new BufferedReader(new InputStreamReader(url.openStream()));
  13.         String mail_regex = ”\\w+@\\w+(\\.\\w+)+”;
  14.         Pattern p = Pattern.compile(mail_regex);
  15.         List<String> list = new ArrayList<String>();
  16.         String line = null;
  17.         while((line = brin.readLine())!=null){
  18.             Matcher m = p.matcher(line);
  19.             while(m.find()){
  20.                 list.add(m.group());
  21.             }
  22.         }
  23.         return list;
  24.     }
  25.     public static List<String> getmail() throws Exception {
  26.         //1.读取源文件
  27.         BufferedReader br = new BufferedReader(new FileReader(“g:\\mymail.html”));
  28.         String mail_regex = ”\\w+@\\w+(\\.\\w)+”;
  29.         Pattern p = Pattern.compile(mail_regex);
  30.         List<String> list = new ArrayList<String>();
  31.         String line = null;
  32.         //2.对读取的数据进行规则的匹配,从中获取符合规则的数据
  33.         while((line = br.readLine())!=null){
  34.             Matcher m = p.matcher(line);
  35.             while(m.find()){
  36.                 //3.将符合规则的数据存储到集合
  37.                 list.add(m.group());
  38.             }
  39.         }
  40.         return list;
  41.     }
  42. }