`

正则表达式 基础知识及常用案例 学习笔记

阅读更多




本文查阅方法:
    1、查阅目录 —— 查阅本文目录,确定想要查阅的目录标题
    2、快捷“查找” —— 在当前浏览器页面,按键 “Ctrl+F” 按键组合,开启浏览器的查找功能,
             在查找搜索框中 输入需要查阅的 目录标题,便可以直接到达 标题内容 的位置。
    3、学习小结 —— 文中的学习小结内容,是笔者在学习之后总结出的,开发时可直接参考其进行应用开发的内容, 进一步加快了本文的查阅 速度。(水平有限,仅供参考。)

 


 

 

本文目录

 

  学习小结

 

  1、正则表达式介绍

 

  2、正则表达式的常用符号及其意义。

 

  3、正则表达式的功能-- 匹配

 

  4、正则表达式的功能-- 切割

 

  5、正则表达式的功能-- 替换

 

  6、正则表达式的功能-- 获取

 

  7、综合Demo样例-- 去除重复叠词

 

  8、综合Demo样例-- 对邮件地址进行校验

 

  9、综合Demo样例-- 将ip地址进行地址段顺序的排序。

 

  10、综合Demo样例-- 网页爬虫(蜘蛛)

​​

   11、《正则表达式 帮助文档》中 部分摘抄(未加整理,仅供参考) ​

 

 


 

 

学习小结

 

  正则表达式:是一种专门用于操作字符串的规则。通过一些符号来表示,简化对字符串的复杂操作。

  弊端:阅读性较差。​

 

  常见的操作:

     (1)匹配:boolean matches(regex)

     (2)切割:String[] split(regex);
     (3)替换:String replaceAll(regex,str);
     (4)获取:(查找) :Pattern , Matcher
            Pattern p=Pattern.compile(regex);
            Matcher m=p.matcher(String);

            while(m.find())
            {
                System.out.println(m.group());
            }

       示例:
            String str="55555562334444577777756666666666";
            String regex="\\d{5,}";
            Pattern p =Pattern.compile(regex);
            Matcher m=p.matcher(str);
            while(m.find())
            {
                String s=m.group();
                s.replaceAll(regex,"#");
            }

 


 

1、正则表达式介绍

 

正则表达式:符合一定规则的表达式。

 

  作用:用于专门操作字符串。

 

  特点:用一些特定的符号来表示一些代码操作。这样就简化书写。

 

  所以学习正则表达式,就是在学习一些特殊符号的使用。

 

 

  好处:可以简化对字符串的复杂操作。

 

  弊端:符号定义越多,正则越长,阅读性越差。

 

 


 

2、正则表达式的常用符号及其意义。

 

  下表是元字符及其在正则表达式上下文中的行为的列表:

 

  字符                描述

 

  (1) \        将下一个字符标记为一个特殊字符、或一个原义字符、或一个 后向引用、或一个八进制转义符。例如,'n' 匹配字符 "n"。'\n' 匹配一个换行符。序列 '\\' 匹配 "\" 而 "\(" 则匹配 "("。

 

  (2) ^      匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 '\n' 或 '\r' 之后的位置。

 

  (3) $        匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性,$ 也匹配 '\n' 或 '\r' 之前的位置。

 

  (4) *        匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。 * 等价于{0,}。

 

  (5) +        匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。

 

  (6) ?        匹配前面的子表达式零次或一次。例如,"do(es)?" 可以匹配 "do" 或 "does" 中的"do" 。? 等价于 {0,1}。

 

  (7) {n}        n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o。

 

  (8) {n,}      n 是一个非负整数。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。

 

  (9) {n,m}      m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。刘, "o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。

 

  (10) ?        当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串 "oooo",'o+?' 将匹配单个 "o",而 'o+' 将匹配所有 'o'。

 

  (11) .        匹配除 "\n" 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符,请使用象 '[.\n]' 的模式。

 

  (12) x|y        匹配 x 或 y。例如,'z|food' 能匹配 "z" 或 "food"。'(z|f)ood' 则匹配 "zood" 或 "food"。 

 

  (13) [xyz]      字符集合。匹配所包含的任意一个字符。例如, '[abc]' 可以匹配 "plain" 中的 'a'。 

 

  (14) [^xyz]      负值字符集合。匹配未包含的任意字符。例如, '[^abc]' 可以匹配 "plain" 中的'p'。 

 

  (15) [a-z]      字符范围。匹配指定范围内的任意字符。例如,'[a-z]' 可以匹配 'a' 到 'z' 范围内的任意小写字母字符。 

 

  (16) [^a-z]       负值字符范围。匹配任何不在指定范围内的任意字符。例如,'[^a-z]' 可以匹配任何不在 'a' 到 'z' 范围内的任意字符。 

 

  (17) \b        匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。 

 

  (18) \B        匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。

 

  (19) \d        匹配一个数字字符。等价于 [0-9]。 

 

  (20) \D        匹配一个非数字字符。等价于 [^0-9]。 

 

  (21) \s        匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。

 

  (22) \w        匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。 

 

  (23) \W        匹配任何非单词字符。等价于 '[^A-Za-z0-9_]'。 

 

  (24)正则表达式中 组 的含义:将部分匹配结果进行封装以便重用。\\num 和 $num  反向引用制定组.

 

  (25) \num      匹配 num,其中 num 是一个正整数。对所获取的匹配的引用。例如,'(.)\1' 匹配两个连续的相同字符。 

 

 


 

3、正则表达式的功能-- 匹配

 

  匹配:String  matches方法。

 

    用规则匹配整个字符串,只要有一处不符合规则,就匹配结束,返回false。

 

 

  Demo样例:  

 

  //匹配手机号段:只有 13xxx 15xxx 18xxxx

 

  public static void checkTel()

 

  {

 

    String tel = "16900001111";

 

    String telReg = "1[358]\\d{9}";

 

    System.out.println(tel.matches(telReg));

 

  }

 

  //匹配字符串

 

  public static void demo()

 

  {

 

    String str = "b23a23456789";

 

 

    String reg = "[a-zA-Z]\\d*";

 

 

    boolean b= str.matches(reg);

 

    System.out.println(b);

 

  }

 

  //匹配QQ号码

 

  public static void checkQQ()

 

  {

 

    String qq = "123a454";

 

 

    String regex = "[1-9]\\d{4,14}";

 

 

    boolean flag = qq.matches(regex);

 

    if(flag)

 

      System.out.println(qq+"...is ok");

 

    else

 

      System.out.println(qq+"... 不合法");

 

  }

 

 


 

 

 

4、正则表达式的功能-- 切割

 

  切割:String[] split();

 

 

 

  Demo样例:

 

  class  RegexDemo

 

  {

 

    public static void main(String[] args) 

 

    {    

 

      splitDemo("zhangsan.lisi.wangwu","\\.");

 

      splitDemo("c:\\abc\\a.txt","\\\\");

 

      splitDemo("erkktyqqquizzzzzo","(.)\\1+");

 

        //按照叠词完成切割。为了可以让规则的结果被重用

 

        //可以将规则封装成一个组。用()完成。组的出现都有编号。

 

        //从1开始。 想要使用已有的组可以通过  \n(n就是组的编号)的形式来获取。

 

    }

 

    public static void splitDemo(String str,String reg)

 

    {

 

 

 

      //String reg = " +";//按照多个空格来进行切割

 

      String[] arr = str.split(reg);  

 

      System.out.println(arr.length);

 

      for(String s : arr)

 

      {

 

        System.out.println(s);

 

      }

 

    }

 

  }

 

 

 


 

5、正则表达式的功能-- 替换

 

  替换:String replaceAll(regex,str);

 

  如果regex中有定义组,可以在第二参数中通过$符号获取正则表达式中的已有的组。

 

 

 

  Demo样例:

 

  class  RegexDemo

 

  {

 

    public static void main(String[] args) 

 

    {

 

      String str = "wer1389980000ty1234564uiod234345675f";//将字符串中的数组替换成#。    

 

      //replaceAllDemo(str,"\\d{5,}","#");

 

 

 

      String str1 = "erkktyqqquizzzzzo";//将叠词替换成$.  //将重叠的字符替换成单个字母。zzzz->z

 

      replaceAllDemo(str1,"(.)\\1+","$1");    

 

    }

 

    public static void replaceAllDemo(String str,String reg,String newStr)

 

    {

 

      str = str.replaceAll(reg,newStr);

 

      System.out.println(str);

 

    }

 

  }

 

 


 

6、正则表达式的功能-- 获取

 

  获取:将字符串中的符合规则的子串取出。

 

  操作步骤:

 

    a,将正则表达式封装成对象。

 

    b,让正则对象和要操作的字符串相关联。

 

    c,关联后,获取正则匹配引擎。

 

    d,通过引擎对符合规则的子串进行操作,比如取出。

 

   典型的调用顺序是 

 

     Pattern p = Pattern.compile("a*b");

 

     Matcher m = p.matcher("aaaaab");

 

     boolean b = m.matches();

 

 

  Demo样例:

 

  import java.util.regex.*;

 

  class RegexDemo2 

 

  {

 

    public static void main(String[] args) 

 

    {

 

      getDemo();

 

    }

 

    public static void getDemo()

 

    {

 

      String str = "ming tian jiu yao fang jia le ,da jia。";

 

      System.out.println(str);

 

      String reg = "\\b[a-z]{4}\\b";

 

 

      //将规则封装成对象。

 

      Pattern p = Pattern.compile(reg);

 

 

      //让正则对象和要作用的字符串相关联。获取匹配器对象。

 

      Matcher m  = p.matcher(str);

 

 

      //System.out.println(m.matches());

 

      //其实String类中的matches方法。用的就是Pattern和Matcher对象来完成的。

 

      //只不过被String的方法封装后,用起来较为简单。但是功能却单一。

 

 

  //    boolean b = m.find();//将规则作用到字符串上,并进行符合规则的子串查找。

 

  //    System.out.println(b);

 

  //    System.out.println(m.group());//用于获取匹配后结果。    

 

 

      //System.out.println("matches:"+m.matches());

 

      while(m.find())

 

      {

 

        System.out.println(m.group());

 

        System.out.println(m.start()+"...."+m.end());

 

      }

 

    }

 

  }

 

 


 

7、综合Demo样例-- 去除重复叠词

 

  到底用四种功能中的哪一个呢?或者哪几个呢?

 

  思路方式:

 

  a,如果只想知道该字符是否对是错,使用匹配。

 

  b,想要将已有的字符串变成另一个字符串,替换。

 

  c,想要按照自定的方式将字符串变成多个字符串。切割。获取规则以外的子串。

 

  d,想要拿到符合需求的字符串子串,获取。获取符合规则的子串。

 

 

  字符串:“我我...我我...我要..要要...要要...学学学....学学...编编编...编程..程.程程...程...程”;

 

  将上面的字符串转成:我要学编程.

 

  public static void test_1()

 

  {

 

    String str = "我我...我我...我要..要要...要要...学学学....学学...编编编...编程..程.程程...程...程";

 

    /*

 

    将已有字符串变成另一个字符串。使用 替换功能。

 

    1,可以先将 . 去掉。

 

    2,在将多个重复的内容变成单个内容。

 

    */

 

    str = str.replaceAll("\\.+","");

 

    System.out.println(str);

 

 

    str = str.replaceAll("(.)\\1+","$1");    

 

    System.out.println(str);

 

  }

 

 


 

8、综合Demo样例-- 对邮件地址进行校验

 

  public static void checkMail()

 

  {

 

    String mail = "abc12@sina.com";

 

    mail = "1@1.1";

 

    String reg = "[a-zA-Z0-9_]+@[a-zA-Z0-9]+(\\.[a-zA-Z]+)+";//较为精确的匹配。

 

    reg = "\\w+@\\w+(\\.\\w+)+";//相对不太精确的匹配。

 

 

    //mail.indexOf("@")!=-1

 

    System.out.println(mail.matches(reg));

 

  }

 

 


 

9、综合Demo样例-- 将ip地址进行地址段顺序的排序。

 

  ip地址:192.68.1.254 102.49.23.013 10.10.10.10 2.2.2.2 8.109.90.30

 

  将上面的ip地址进行地址段顺序的排序。

 

  思路:还按照字符串自然顺序,只要让它们每一段都是3位即可。

 

  a,按照每一段需要的最多的0进行补齐,那么每一段就会至少保证有3位。

 

  b,将每一段只保留3位。这样,所有的ip地址都是每一段3位。

 

  public static void ipSort()

 

  {

 

    String ip = "192.68.1.254 102.49.23.013 10.10.10.10 2.2.2.2 8.109.90.30";

 

 

    ip = ip.replaceAll("(\\d+)","00$1");

 

    System.out.println(ip);

 

 

    ip = ip.replaceAll("0*(\\d{3})","$1");

 

    System.out.println(ip);

 

 

    String[] arr = ip.split(" ");

 

 

    //或者使用 Array.sort().方法也可以。

 

    TreeSet<String> ts = new TreeSet<String>();

 

 

    for(String s : arr)

 

    {

 

      ts.add(s);

 

    }

 

 

    for(String s : ts)

 

    {

 

      System.out.println(s.replaceAll("0*(\\d+)","$1"));

 

    }

 

  }

 

 


 

10、综合Demo样例-- 网页爬虫(蜘蛛)

 

  import java.io.*;

 

  import java.util.regex.*;

 

  import java.net.*;

 

  import java.util.*;

 

  class RegexTest2 

 

  {

 

    public static void main(String[] args) throws Exception

 

    {

 

      getMails_1();

 

    }

 

    public static void getMails_1()throws Exception

 

    {

 

      URL url = new URL("http://192.168.1.254:8080/myweb/mail.html");

 

      URLConnection conn = url.openConnection();

 

      BufferedReader bufIn = 

 

        new BufferedReader(new InputStreamReader(conn.getInputStream()));

 

 

      String line = null;

 

      String mailreg = "\\w+@\\w+(\\.\\w+)+";

 

      Pattern p = Pattern.compile(mailreg);      

 

 

      while((line=bufIn.readLine())!=null)

 

      {

 

        Matcher m = p.matcher(line);

 

        while(m.find())

 

        {

 

          System.out.println(m.group());

 

        }

 

      }

 

    }

 

 

    /*

 

    获取指定文档中的邮件地址。

 

    使用获取功能。Pattern  Matcher

 

    */

 

    public static void getMails()throws Exception

 

    {

 

      BufferedReader bufr = 

 

        new BufferedReader(new FileReader("mail.txt"));

 

 

      String line = null;

 

      String mailreg = "\\w+@\\w+(\\.\\w+)+";

 

      Pattern p = Pattern.compile(mailreg);

 

      while((line=bufr.readLine())!=null)

 

      {

 

        Matcher m = p.matcher(line);

 

        while(m.find())

 

        {

 

          System.out.println(m.group());

 

        }

 

      }

 

    }

 

  }

 

 

素材资料:mail.txt文件

 

skdajflksadjflk> abc0@sina.com<djfsa;lkdfjksa;ljfs;alfjsa;lkjfsa;lkfjska;ljfsafsd;​

 

skdajflksadjflkdjfsa;lkdfjksa;ljfs;alfjsa;lkjfsa;lkfjska;ljfsafsd

 

skdajfl> abc1@sina.com<ksadjflkdjfsa;lkdfjksa;ljfs;alfjsa;lkjfsa;lkfjska;ljfsafsd

 

skdajflksadjflkdjfsa;lkdfjksa;ljfs;alfjsa;lkjfsa;lkfjska;ljfsafsd

 

skdajfl> abc2@sina.com<sadjflkdjfsa;lkdfjks> abc3@sina.com<a;ljfs;alfjsa;lkjfsa;lkfjska;ljfsafsd

 

skdajflksadjflkdjfsa;lkdfjksa;ljfs;alfjsa;lkjfsa;lkfjska;ljfsafsd

 

skdajflksadjflkdjfsa;lkv> ab4c@sina.com<dfjksa;ljfs;alfjsa;lkjfsa;lkfjska;ljfsafsd

 

skdajf> abc5@sina.com<ksadjflkdjfsa;lkdfjksa;ljfs;alfjsa;lkjfsa;lkfjska;ljfsafsd

 

skdajflksadjflkdjfsa;lkdfjksa;ljfs;alfjsa;lkjfsa;lkfjska;ljfsafsd

 

skdajflksadjf> abc6@sina.com<lkdjfsa;lkdfjksa;ljfs;alfjsa;lkjfsa;lkfjska;ljfsafsd

 

skdajflksadjflkdjfsa;lkd> abc7@sina.com<fjksa;ljfs;alfj> abc8@sina.com<sa;lkjfsa;lkfjska;ljfsafsd

 

skdajflksadjflkdjfsa;lkdfjksa;ljfs;alfjsa;lkjfsa;lkfjska;ljfsafsd

 

skdajflks> abc11@sina.com<adjflkdjfsa;> abc9@sina.com<lkdfjksa;ljfs;alfjsa;lkjfsa;lkfjska;ljfsafsd

 

skdajflksadjflkdjfsa;lkdfjksa;ljfs;alfjsa;lkjfsa;lkfjska;ljfsafsd

 

skdajflksadjf> abc12@sina.com<lkdjfsa;lk> abc55@sina.com<dfjksa;ljfs;alfjsa;lkjfsa;lkfjska;ljfsafsd

 

skdajflksadjflk> abc123@sina.com<djfsa;lkdfjksa;ljfs;alfjsa;lkjfs> abc1234@sina.com<a;lkfjska;ljfsafsd

 

sdfsakfjask;lfjsak;lfj qqq@sina.com aslk;fjsafsafsafs

 

 


​​

11、《正则表达式 帮助文档》中 部分摘抄(未加整理,仅供参考) ​

 

正则表达式中乱七八糟的组合很多,下面是js帮助文档中的说明,放这里以备查

正则表达式对象

本对象包含正则表达式模式以及表明如何应用模式的标志。

语法 1

re = /pattern/[flags]

语法 2

re = new RegExp("pattern",["flags"]) 

参数

re

必选项。将要赋值为正则表达式模式的变量名。

Pattern 

必选项。要使用的正则表达式模式。如果使用语法 1,用 "/" 字符分隔模式。如果用语法 2,用引号将模式引起来。

flags

可选项。如果使用语法 2 要用引号将 flag 引起来。标志可以组合使用,可用的有: 

· (全文查找出现的所有 pattern) 

· (忽略大小写) 

· (多行查找) 

说明

不要将正则表达式对象跟全局 RegExp 对象混淆。尽管听起来像是一回事,但它们是截然不同的。正则表达式对象的属性只包含一个正则表达式的信息,而全局 RegExp 对象的属性包含了不断更新的每一个匹配出现的信息。

正则表达式对象保存用于查找字符串中的字符组合时的模式。创建正则表达式对象后,或者它被传递给字符串方法,或者字符串被传递给一个正则表达式方法。有关最近进行查找的信息被保存在全局 RegExp 对象中。

当预先知道查找字符串时用语法 1。当查找字符串经常变动或不知道时用语法 2,比如由用户输入得到的字符串。

在使用前 pattern 参数被编译为内部格式。对语法 1 来说,pattern 在该脚本被装载时被编译。对语法 2 来说,pattern 在使用前,或调用 compile 方法时被编译。 

示例

下面的示例创建一个包含正则表达式模式及相关标志的对象(re),向您演示正则表达式对象的用法。在本例中,作为结果的正则表达式对象又用于 match 方法中:

function MatchDemo(){

   var r, re;                     // 声明变量。

   var s = "The rain in Spain falls mainly in the plain";

   re = new RegExp("Spain","i");  // 创建正则表达式对象。

   r = s.match(re);               // 在字符串 s 中查找匹配。

   return(r);                     // 返回匹配结果。

}

 

正则表达式语法

一个正则表达式就是由普通字符(例如字符 a 到 z)以及特殊字符(称为元字符)组成的文字模式。该模式描述在查找文字主体时待匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。

这里有一些可能会遇到的正则表达式示例:

JScript

VBScript

匹配

/^\[ \t]*$/

"^\[ \t]*$"

匹配一个空白行。

/\d{2}-\d{5}/

"\d{2}-\d{5}"

验证一个ID 号码是否由一个2位数字,一个连字符以及一个5位数字组成。

/<(.*)>.*<\/\1>/

"<(.*)>.*<\/\1>"

匹配一个 HTML 标记。

 

下表是元字符及其在正则表达式上下文中的行为的一个完整列表:

字符

描述

\

将下一个字符标记为一个特殊字符、或一个原义字符、或一个 后向引用、或一个八进制转义符。例如,'n' 匹配字符 "n"。'\n' 匹配一个换行符。序列 '\\' 匹配 "\" 而 "\(" 则匹配 "("。

^

匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 '\n' 或 '\r' 之后的位置。

$

匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性,$ 也匹配 '\n' 或 '\r' 之前的位置。

*

匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。 * 等价于{0,}。

+

匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。

?

匹配前面的子表达式零次或一次。例如,"do(es)?" 可以匹配 "do" 或 "does" 中的"do" 。? 等价于 {0,1}。

{n}

n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o。

{n,}

n 是一个非负整数。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。

{n,m}

m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。刘, "o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。

?

当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串 "oooo",'o+?' 将匹配单个 "o",而 'o+' 将匹配所有 'o'。

.

匹配除 "\n" 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符,请使用象 '[.\n]' 的模式。

(pattern)

匹配pattern 并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到,在VBScript 中使用 SubMatches 集合,在JScript 中则使用 $0$9 属性。要匹配圆括号字符,请使用 '\(' 或 '\)'。

(?:pattern)

匹配 pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用 "或" 字符 (|) 来组合一个模式的各个部分是很有用。例如, 'industr(?:y|ies) 就是一个比 'industry|industries' 更简略的表达式。

(?=pattern)

正向预查,在任何匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如, 'Windows (?=95|98|NT|2000)' 能匹配 "Windows 2000" 中的 "Windows" ,但不能匹配 "Windows 3.1" 中的 "Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。

(?!pattern)

负向预查,在任何不匹配Negative lookahead matches the search string at any point where a string not matching pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如'Windows (?!95|98|NT|2000)' 能匹配 "Windows 3.1" 中的 "Windows",但不能匹配 "Windows 2000" 中的 "Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始 

x|y

匹配 x 或 y。例如,'z|food' 能匹配 "z" 或 "food"。'(z|f)ood' 则匹配 "zood" 或 "food"。 

[xyz]

字符集合。匹配所包含的任意一个字符。例如, '[abc]' 可以匹配 "plain" 中的 'a'。 

[^xyz]

负值字符集合。匹配未包含的任意字符。例如, '[^abc]' 可以匹配 "plain" 中的'p'。 

[a-z]

字符范围。匹配指定范围内的任意字符。例如,'[a-z]' 可以匹配 'a' 到 'z' 范围内的任意小写字母字符。 

[^a-z]

负值字符范围。匹配任何不在指定范围内的任意字符。例如,'[^a-z]' 可以匹配任何不在 'a' 到 'z' 范围内的任意字符。 

\b

匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。 

\B

匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。

\cx

匹配由x指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。 x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 'c' 字符。 

\d

匹配一个数字字符。等价于 [0-9]。 

\D

匹配一个非数字字符。等价于 [^0-9]。 

\f

匹配一个换页符。等价于 \x0c 和 \cL。

\n

匹配一个换行符。等价于 \x0a 和 \cJ。

\r

匹配一个回车符。等价于 \x0d 和 \cM。

\s

匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。

\S

匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。

\t

匹配一个制表符。等价于 \x09 和 \cI。

\v

匹配一个垂直制表符。等价于 \x0b 和 \cK。

\w

匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。 

\W

匹配任何非单词字符。等价于 '[^A-Za-z0-9_]'。 

\xn

匹配 n,其中 n 为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如, '\x41' 匹配 "A"。'\x041' 则等价于 '\x04' & "1"。正则表达式中可以使用 ASCII 编码。.

\num

匹配 num,其中 num 是一个正整数。对所获取的匹配的引用。例如,'(.)\1' 匹配两个连续的相同字符。 

\n

标识一个八进制转义值或一个后向引用。如果 \n 之前至少 n 个获取的子表达式,则 n 为后向引用。否则,如果 n 为八进制数字 (0-7),则 n 为一个八进制转义值。

\nm

标识一个八进制转义值或一个后向引用。如果 \nm 之前至少有is preceded by at least nm 个获取得子表达式,则 nm 为后向引用。如果 \nm 之前至少有 n 个获取,则 n 为一个后跟文字 的后向引用。如果前面的条件都不满足,若  n 和 m 均为八进制数字 (0-7),则 \nm 将匹配八进制转义值 nm

\nml

如果 n 为八进制数字 (0-3),且 m 和 l 均为八进制数字 (0-7),则匹配八进制转义值 nml。

\un

匹配 n,其中 n 是一个用四个十六进制数字表示的 Unicode 字符。例如, \u00A9 匹配版权符号 (?)。

 

Java帮助文档中的正则表达式:

java.util.regex 
类 Pattern

public final class Pattern

extends Object

implements Serializable

正则表达式的编译表示形式。 

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

因此,典型的调用顺序是 

 Pattern p = Pattern.compile("a*b");

 Matcher m = p.matcher("aaaaab");

 boolean b = m.matches();

在仅使用一次正则表达式时,可以方便地通过此类定义 matches 方法。此方法编译表达式并在单个调用中将输入序列与其匹配。语句 

 boolean b = Pattern.matches("a*b", "aaaaab");

等效于上面的三个语句,尽管对于重复的匹配而言它效率不高,因为它不允许重用已编译的模式。 

此类的实例是不可变的,可供多个并发线程安全使用。Matcher 类的实例用于此目的则不安全。

正则表达式的构造摘要 

构造

匹配

 

 

字符

x

字符 x

\\

反斜线字符

\0n

带有八进制值 0 的字符 n (0 <= n <= 7)

\0nn

带有八进制值 0 的字符 nn (0 <= n <= 7)

\0mnn

带有八进制值 0 的字符 mnn<= m <= 3<= n <= 7

\xhh

带有十六进制值 0x 的字符 hh

\uhhhh

带有十六进制值 0x 的字符 hhhh

\t

制表符 ('\u0009')

\n

新行(换行)符 ('\u000A')

\r

回车符 ('\u000D')

\f

换页符 ('\u000C')

\a

报警 (bell) 符 ('\u0007')

\e

转义符 ('\u001B')

\cx

对应于 x 的控制符

 

 

字符类

[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](减去)

 

 

预定义字符类

.

任何字符(与行结束符可能匹配也可能不匹配)

\d

数字:[0-9]

\D

非数字: [^0-9]

\s

空白字符:[ \t\n\x0B\f\r]

\S

非空白字符:[^\s]

\w

单词字符:[a-zA-Z_0-9]

\W

非单词字符:[^\w]

 

 

POSIX 字符类(仅 US-ASCII

\p{Lower}

小写字母字符:[a-z]

\p{Upper}

大写字母字符:[A-Z]

\p{ASCII}

所有 ASCII[\x00-\x7F]

\p{Alpha}

字母字符:[\p{Lower}\p{Upper}]

\p{Digit}

十进制数字:[0-9]

\p{Alnum}

字母数字字符:[\p{Alpha}\p{Digit}]

\p{Punct}

标点符号:!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~

\p{Graph}

可见字符:[\p{Alnum}\p{Punct}]

\p{Print}

可打印字符:[\p{Graph}\x20]

\p{Blank}

空格或制表符:[ \t]

\p{Cntrl}

控制字符:[\x00-\x1F\x7F]

\p{XDigit}

十六进制数字:[0-9a-fA-F]

\p{Space}

空白字符:[ \t\n\x0B\f\r]

 

 

java.lang.Character 类(简单的 java 字符类型

\p{javaLowerCase}

等效于 java.lang.Character.isLowerCase()

\p{javaUpperCase}

等效于 java.lang.Character.isUpperCase()

\p{javaWhitespace}

等效于 java.lang.Character.isWhitespace()

\p{javaMirrored}

等效于 java.lang.Character.isMirrored()

 

 

Unicode 块和类别的类

\p{InGreek}

Greek 块(简单)中的字符

\p{Lu}

大写字母(简单类别

\p{Sc}

货币符号

\P{InGreek}

所有字符,Greek 块中的除外(否定)

[\p{L}&&[^\p{Lu}]] 

所有字母,大写字母除外(减去)

 

 

边界匹配器

^

行的开头

$

行的结尾

\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 次

 

 

Reluctant 数量词

X??

X,一次或一次也没有

X*?

X,零次或多次

X+?

X,一次或多次

X{n}?

X,恰好 n 次

X{n,}?

X,至少 n 次

X{n,m}?

X,至少 n 次,但是不超过 m 次

 

 

Possessive 数量词

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 捕获组

 

 

引用

\

Nothing,但是引用以下字符

\Q

Nothing,但是引用所有字符,直到 \E

\E

Nothing,但是结束从 \Q 开始的引用

 

 

特殊构造(非捕获)

(?:X)

X,作为非捕获组

(?idmsux-idmsux) 

Nothing,但是将匹配标志i d m s u x on - off

(?idmsux-idmsux:X)  

X,作为带有给定标志 i d m s u x on - off非捕获组 

(?=X)

X,通过零宽度的正 lookahead

(?!X)

X,通过零宽度的负 lookahead

(?<=X)

X,通过零宽度的正 lookbehind

(?<!X)

X,通过零宽度的负 lookbehind

(?>X)

X,作为独立的非捕获组

 

斜线、转义和引用 

反斜线字符 ('\') 用于引用转义构造,如上表所定义的,同时还用于引用其他将被解释为非转义构造的字符。因此,表达式 \\ 与单个反斜线匹配,而 \{ 与左括号匹配。 

在不表示转义构造的任何字母字符前使用反斜线都是错误的;它们是为将来扩展正则表达式语言保留的。可以在非字母字符前使用反斜线,不管该字符是否非转义构造的一部分。 

根据 Java Language Specification 的要求,Java 源代码的字符串中的反斜线被解释为 Unicode 转义或其他字符转义。因此必须在字符串字面值中使用两个反斜线,表示正则表达式受到保护,不被 Java 字节码编译器解释。例如,当解释为正则表达式时,字符串字面值 "\b" 与单个退格字符匹配,而 "\\b" 与单词边界匹配。字符串字面值 "\(hello\)" 是非法的,将导致编译时错误;要与字符串 (hello) 匹配,必须使用字符串字面值 "\\(hello\\)"

字符类 

字符类可以出现在其他字符类中,并且可以包含并集运算符(隐式)和交集运算符 (&&)。并集运算符表示至少包含其某个操作数类中所有字符的类。交集运算符表示包含同时位于其两个操作数类中所有字符的类。 

字符类运算符的优先级如下所示,按从最高到最低的顺序排列: 

1    

字面值转义    

\x

2    

分组

[...]

3    

范围

a-z

4    

并集

[a-e][i-u]

5    

交集

[a-z&&[aeiou]]

注意,元字符的不同集合实际上位于字符类的内部,而非字符类的外部。例如,正则表达式 . 在字符类内部就失去了其特殊意义,而表达式 - 变成了形成元字符的范围。

行结束符

行结束符 是一个或两个字符的序列,标记输入字符序列的行结尾。以下代码被识别为行结束符: 

· 新行(换行)符 ('\n')、 

· 后面紧跟新行符的回车符 ("\r\n")、 

· 单独的回车符 ('\r')、 

· 下一行字符 ('\u0085')、 

· 行分隔符 ('\u2028'或 

· 段落分隔符 ('\u2029)。 

如果激活 UNIX_LINES 模式,则新行符是唯一识别的行结束符。 

如果未指定 DOTALL 标志,则正则表达式 . 可以与任何字符(行结束符除外)匹配。 

默认情况下,正则表达式 ^ 和 $ 忽略行结束符,仅分别与整个输入序列的开头和结尾匹配。如果激活 MULTILINE 模式,则 ^ 在输入的开头和行结束符之后(输入的结尾)才发生匹配。处于 MULTILINE 模式中时,$ 仅在行结束符之前或输入序列的结尾处匹配。

组和捕获 

捕获组可以通过从左到右计算其开括号来编号。例如,在表达式 ((A)(B(C))) 中,存在四个这样的组: 

1    

((A)(B(C)))

2    

\A

3    

(B(C))

4    

(C)

组零始终代表整个表达式。 

之所以这样命名捕获组是因为在匹配中,保存了与这些组匹配的输入序列的每个子序列。捕获的子序列稍后可以通过 Back 引用在表达式中使用,也可以在匹配操作完成后从匹配器获取。 

与组关联的捕获输入始终是与组最近匹配的子序列。如果由于量化的缘故再次计算了组,则在第二次计算失败时将保留其以前捕获的值(如果有的话)例如,将字符串 "aba" 与表达式 (a(b)?)+ 相匹配,会将第二组设置为 "b"。在每个匹配的开头,所有捕获的输入都会被丢弃。 

以 (?) 开头的组是纯的非捕获 组,它不捕获文本,也不针对组合计进行计数。

 

 

 

 


 

​敬请评论

(1)若您觉得本文 有用处  —— 请留言评论,以坚定其他 IT童鞋 阅读本文的信心。

(2)若您觉得本文 没用处  —— 请留言评论,笔者将会改进不足,以便为大家整理更加好用的笔记。

 


 

 

 

0
5
分享到:
评论
1 楼 User_Java 2013-06-15  
楼主是个有心人啊!这种精神非常值得学习!

相关推荐

Global site tag (gtag.js) - Google Analytics