在Java中的正则表达式,必须首先被编译为java.util.regex.Pattern的实例。然后,可将得到的模式用于创建Matcher对象,依照正则表达式,该对象可以与任意字符序列匹配。 执行匹配所涉及的所有状态都驻留在匹配器中,所以多个匹配器可以共享同一模式。
因此,典型的调用顺序是
    Pattern p=Pattern.compile("a*b");
    Matcher m=p.matcher("aaaaaab");
    boolean b=m.matches();
在仅使用一次正则表达式时,可以方便地通过此类定义mathces方法。此方法编译表达式并在单个调用中将输入序列与其匹配。语句
    boolean b=Pattern.matches("a*b","aaaaaab");
等效于上面的三个语句,尽管对于重复的匹配而言它效率不高,因为它不允许重用已编译的模式。
    1. 基本内容
  • 字符类
字符 说明
[abc] a,b或c中的某一个
[^abc] 非a,b或c中的任何一个
[a-zA-Z] a到z或A到Z,两头的字母包括在内
[a-d[m-p]] a到d与m到p(并集),等同于[a-dm-p]
[a-z&&[def]] d,e或f(交集)
[a-z&&[^bc]] a到z除了bc,等同于[ad-z](减去)
[a-z&&[^m-p]] a到z而非m到p(减去)
    • 预定义字符
    字符 说明
    . 任何字符
    \d 数字
    \D 非数字
    \s 任何空白字符
    \S 任何非空白字符
    \w 单词字符(字母,数字,下划线)
    \W 非单词字符,等同于[^\w]
      • 边界匹配器
      字符 说明
      ^ 行的开始
      $ 行的结束
      \b 单词边界
      \B 非单词边界
      \A 输入开始
      \Z 输入的结尾,仅用于最后一个结束符(如果有)
      \z 输入的结尾
      \G 上一个匹配的结尾
        • 数量词
        字符 说明
        X? 匹配X0到一次
        X* 匹配X0到多次
        X+ 匹配X一到多次
        X{n} 匹配X恰好n次
        X{n,} 匹配X至少n次
        X{n,m} 匹配Xn到m次
          • 运算符
          字符 说明
          XY X后跟Y
          X|Y X或Y
          (X) X,作为捕获组
            • 引用
            字符 说明
            \n 任何匹配的捕获组
              • 反斜线,转义和引用

                  反斜线(“\”)用于引用转义构造,同时还用于引用其他将被解释为非转义构造的字符。因此,表达式\\表示单个反斜线,而\{与左括号匹配。在不表示转义构造的任何字母字符前使用反斜线都是错误的;它们是为将来扩展正则表达式语言保留的。可以在非字母字符前使用反斜线,不管该字符是否非转义构造的一部分。

                   根据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]]
                  • 组和捕获

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

                  1. ((A)(B(C)))
                  2. \A
                  3. (B(C))
                  4. (C)

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

                    1. 正则表达式对字符串的常见操作
                  • 匹配
                                  /*
                                   *匹配手机号码
                                  */
                                  public static void function_demo1(){
                                      String str="15839098373";
                                      String regex="1[3578]\\d{9}";\\"\\d"可换成{0-9}
                                      boolean b=str.matches(regex);
                                      System.out.println(b);
                                  }
                              
                    • 切割
                                    切割实际上就是String的split方法,此方法接收一个正则表达式字符串作为参数
                                    /*
                                     *切割以下字符串"a b c d e"
                                    */
                                    public static void function_demo2() {
                                        String str="a b c d e";
                                        String[] ch=str.split(" ");
                                        for (String string : ch) {
                                            System.out.println(string);
                                        }
                                    }
                                    运行结果:
                                    a
                                    b
                                    c
                                    d
                                    e
                                    情境一:但是当字符串中间的空格数不确定时,如"a    b        c  d   e",此时再用split直接使用空格进行切割便得不到预想的结果;
                                            此时,可用" +"正则表达式进行切割;即str.split(" +");
                                    情境二:当字符串为“a.b.c.d.e”时,此时再用“.”进行切割将得不到任何结果,因为“.”在正则表达式中代表任何字符,可使用"\\."进行转义;
                                    情境三:当字符串为“a###b@@@c$$d##e”或“attttttbmmmmcnnnn”时,该如何切割出abcde?先揭示一下正则表达式的写法:str.split("(.)\\1+");
                                           解释一下"(.)\\1+":“.”在正则表达式中代码任意字符,我们想要去除的是字符串中重复的字符即字符出现的次数多于一次;“(.)”代表一
                                    个组,组中的“.”即任意字符,那么接下来就是要用正则表达式去让这个组能重复的出现。前面在讲捕获组的时候有说过每个字符串可以以左括号来区
                                    分组的编号,组零代表整个表达式即“(.)”;前面在讲引用的时候“\n”代表所引用的组,那么在这个示例中“\1”代表引用的是组1的编号中的内容
                                    即“.”;“+”代表出现一次或多次;综合起来这个正则表达式的意思就是连续出现一次或多次的字符;
                                
                      • 替换
                                      替换实际上用的是字符串的replaceAll方法,此方法接收两个参数,第一个参数为正则表达式,第二个参数为替换的字符串
                                      /*
                                       *替换“attttbnnnnc”中连续出现的字符为e
                                      */
                                      public static void function_demo4() {
                                          String str="attttbnnnnc";
                                          String regex="(.)\\1+";
                                          System.out.println(str.replaceAll(regex, "e"));
                                      }
                                      情境一:把上面字符串中连续出现的字符替换为一个,即替换为“atbnc”,str.replaceAll(regex,"$1")即可,“$1”代表拿前面被替换组中的字符
                                      情境二:把手机号码“15890875345”的中间四位用“*”隐藏掉
                                      public static void function_demo5() {
                                          String string="15890987656";
                                          String regex="(\\d{3})(\\d{4})(\\d{4})";
                                          System.out.println(string.replaceAll(regex, "$1****$3"));
                                      }
                                      情境三:把字符串中的所有圆括号(中,英,全角,半角)替换为“*”
                                      public static void function_demo3() {
                                          String str="a((((((((b(((((((c))))))))))))d()()0)e";
                                          String regex="([\\(|(|\\)|)])";
                      
                                          System.out.println(str.replaceAll(regex, "*"));
                                      }
                                  
                        • 获取
                                        因正则表达式会被编译为Pattern的实例,然后可用Pattern的matcher方法获取Matter对象,然后用Matter对象的实例方法进行相关的一些操作
                                        /*
                                         *获取字符串中以三个字母组成的单词的字符串,“jin tian shi ge hao tian qi , xia le yi dian xiao yu”
                                        */
                                        public static void function_demo6() {
                                            String str = "jin tian shi ge hao tian qi , xia le yi dian xiao yu";
                                            String regex = "\\b[a-z]{3}\\b";// "\b"确定单词边界
                                            Pattern p = Pattern.compile(regex);//获取编译的Pattern对象
                                            Matcher m = p.matcher(str);//通过Pattern对象获取Matcher对象的实例
                                            while (m.find()) {//查找与该模式匹配的输入序列的下一个子序列
                                                System.out.println(m.group());//返回在以前匹配操作期间由给定组捕获的输入子序列
                                            }
                                        }
                                    

                        练习

                        一,治疗口吃

                                /*
                                 *“我我我我我我我我我......不不不不不不不不不不不不不不不......是是是是是......药药药药药......神神神神神......”
                                 */
                                public static void function_exercise1(){
                                    String str="我我我我我我我我我......不不不不不不不不不不不不不不不......是是是是是......药药药药药......神神神神神......";
                                    str=str.replaceAll("\\.","");//先把字符串中的“.”去掉
                                    String regex="(.)\\1+";//把字符串中的重复字体去除的正则表达式
                                    System.out.println(str.replaceAll(regex,"$1"));
                                }
                            

                        二,对IP地址按照A类B类C类D类E类进行排序(不理解IP地址分类的可以去百度一下)

                                /*
                                 *"192.168.0.1  89.123.0.1   3.3.3.3   156.0.231.5"对IP地址字符串进行排序
                                 *操作思路:IP地址是用点分十进制的形式由32位的二进制被划分成了四段,每段8位转成十进制而形成的,每段范围0-255
                                 *为了用TreeSet对对象进行排序,所以需要对每个IP地址的每一段进行等位补充,比如地址中的某一段是一位数的补为三位
                                 *数,然后放到TreeSeet中进行排序
                                 */
                                public static void function_demo7() {
                                    String ip_str="192.168.0.1  89.123.0.1   3.3.3.3   156.0.231.5";
                                    String[] ip_strArry=ip_str.split(" +");//把IP地址用空格打散成一个字符数组
                                    TreeSet ts=new TreeSet<>();//用TreeSet对对象进行排序
                                    System.out.println("排序前:");
                                    for(String str:ip_strArry) {
                                        System.out.println(str);
                                        str=str.replaceAll("(\\d+)", "00$1");//把每一段的数值前补充两个零,此时192.168.0.1变成了00192.00168.000.001
                                                                             //而3.3.3.3变成了003.003.003.003
                                        str=str.replaceAll("0*(\\d{3})", "$1");//把IP地址变为五位的,如00192,前两位的零去除,此时每个IP地址的每一段都是三位数
                                        ts.add(str);//放入TreeSet中,默认排序
                                    }
                                    System.out.println("------------------");
                                    System.out.println("排序后:");
                                    for(String str:ts) {
                                    str=str.replaceAll("0*(\\d+)", "$1");//把003这样的段位的前两个零去除
                                    System.out.println(str);
                                    }
                                }
                            

                        三,网络爬虫

                                /*
                                 *爬取网页上面的邮箱号
                                 */
                                public static void function_demo8() throws IOException {
                                    URL url=new URL("http://localhost:63342/BoKeYuanComplieProject/regex.html");//需要抓取的网页地址
                                    //BufferedReader br = new BufferedReader(new FileReader("C:\\regex.html"));//抓取的本地文件
                                    BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
                                    String regex="\\w+@\\w+\\.([a-zA-Z]{1,3}){1,2}";//邮箱
                                    Pattern p=Pattern.compile(regex);//把正则编译为Pattern对象
                                    List list=new ArrayList();//存放抓取后的邮箱信息
                                    String line = null;
                                    while ((line = br.readLine()) != null) {
                                        Matcher m=p.matcher(line);
                                        if(m.find()) {
                                            list.add(m.group());
                                        }
                                    }
                                    for(String str:list) {
                                        System.out.println(str);
                                    }
                                }
                            

                        相关文章:

                        • 2022-12-23
                        • 2022-12-23
                        • 2021-07-02
                        • 2022-01-15
                        • 2022-12-23
                        • 2022-12-23
                        • 2022-12-23
                        猜你喜欢
                        • 2021-11-16
                        • 2022-12-23
                        • 2021-12-12
                        • 2022-12-23
                        • 2022-12-23
                        • 2021-11-22
                        • 2021-12-04
                        相关资源
                        相似解决方案