欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-03-02 10:37:24
...




本文查阅方法:
    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)若您觉得本文 没用处  —— 请留言评论,笔者将会改进不足,以便为大家整理更加好用的笔记。