zoukankan      html  css  js  c++  java
  • Java:正则表达式的详解

    正则表达式:符合一定规则的表达式。
    作用:用于专门操作字符串。
    特点:用一些特定的符号来表示一些代码的操作.这样就简化书写。所以学习正则表达式就是学习一些特殊符号的使用。
    好处:可以简化对字符串的操作。
    弊端:符号定义越多,正则越长,阅读性越差。
     
    具体操作功能:
      1.匹配    boolean matches(String regex) 告知此字符串是否匹配给定的正则表达式。
                    用规则匹配整字符串,只要有一处不符合规则,就匹配结束,返回false  
     
      2.切割    String[] split(String regex) 根据给定正则表达式的匹配拆分此字符串。
     
     
      3.替换    String replaceAll(String regex, String replacement)
    使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。 
               
    String replaceFirst(String regex, String replacement)
    使用给定的 replacement 替换此字符串匹配给定的正则表达式的第一个子字符串。
    对上面的三种进行演示如下:
    class RegexDemo
    {
        public static void main(String[] args)
        {
            //CheckQQ_1();
            //CheckQQ();
            //demo();
            //CheckTel();
            //SplitDemo();
            ReplaceDemo();
        }
    
       //替换演示
       public static void ReplaceDemo()
       {
            //String str = "123dffhe568kkkdsr7885445e";//要求:将字符串的数字替换成‘#’
            //String regex = "\d{5,}";//可以规定超过5个数字就将数字替换成‘#’
            //String s = "#";
            
            //String str = "zhakksxsqqwanwwwwu";//将叠词进行替换'&'
            //String regex = "(.)\1+";
            //String s = "&";    
    
            String str = "zhakksxsqqwanwwwwu";//将叠词字符由多个变成一个
            String regex = "(.)\1+";
            String s = "$1";            
            
            System.out.println(str.replaceAll(regex,s));
       }   
        
        //切割演示
        public static void SplitDemo()
        {
            //String  str = "zhangsan    lisi wangwu";
            //String regex = " +";     //一次或多次空格
            
            //String  str = "zhangsan.lisi.wangwu";
            //String regex = "\.";    //特殊字符,对点和反斜杠进行转义
            
            //String  str = "zhangsan,lisi,wangwu";
            //String regex = ",";   
    
            //String  str = "c:\zhangsan\lisi\wangwu";
            //String regex = "\\";
    
    
            String  str = "zhakksxsqqwanwwu";//按照叠词进行切割
            String regex = "(.)\1+";//第一次切割的结果为组被重用,接着进行后面一次或多次的切割(每一个组按照顺序有编号,反向引用第一组)        
            
            String[] arr = str.split(regex);
            
            for(String s: arr)
            {
                System.out.println(s);
            }
        }
        //匹配字符演示
        public static void demo()
        {
            String str = "a";
            String regex = "[bcd]";//给定要比较的字符串中内容必须只能是规则中的某一个字符。
            boolean b = str.matches(regex);
            System.out.println(b);//false
        }
        
    //匹配手机号 13xxx,15xxx,18xxx public static void CheckTel() { String tel = "15000000000"; String regex = "[1][358]\d{9}";//"[1][358]\d{3,10}" System.out.println(tel.matches(regex)); }
    //匹配QQ号
    public static void CheckQQ() { String qq = "01237458"; //String regex = "[1-9][0-9]{4,14}"; String regex = "[1-9]\d{4,14}"; boolean flag = qq.matches(regex); if(flag) System.out.println("qq:"+qq); else System.out.println("qq不符合要求!"); } /* 需求:对QQ号码进行校验 要求:5~15位,0不能开头,只能是数字 这种方式是使用String类中的方法,进行组合完成了需求,但是代码过于复杂。 */ public static void CheckQQ_1() { String qq = "1237458"; int len = qq.length(); if(len>=5 && len<=15) { if(!qq.startsWith("0"))//qq.chatAt(0)==0 //Integer.parseInt("12a") NumberFormatException { try { long l = Long.parseLong(qq); System.out.println("qq:"+qq); } catch(NumberFormatException e) { System.out.println("qq出现非法字符......"); } /* char[] arr = qq.toCharArray(); boolean flag = true; for(int i=0;i<arr.length;i++) { if(!(arr[i]>='0' && arr[i]<='9')) { flag = false; break; } } if(flag) { System.out.println("qq:"+qq); } else { System.out.println("qq出现非法字符!"); } */ } else { System.out.println("qq不能以0开头!"); } } else { System.out.println("qq号长度错误,请重新输入!"); } } }
    java.util.regex 
    类 Pattern(final):正则表达式的编译表示形式。 
    static Pattern compile(String regex) 
     将给定的正则表达式编译到模式中。 
     
    java.util.regex 
    类 Matcher(final):通过解释 Pattern 对 character sequence 执行匹配操作的引擎。  
    int end() 
     返回最后匹配字符之后的偏移量(最后但不包括的索引)。
    int start() 
     返回以前匹配的初始索引。
                 String group() 
                  返回由以前匹配操作所匹配的输入子序列。  
     
    正则表达式的第四个功能:
    4. 获取:将字符串中符合规则的子串取出来。
     
    操作步骤:
           (1)将正则表达式封装成对象;
      (2)让正则对象与要操作的字符串关联;
      (3)关联后,获取一个正则匹配引擎(匹配器);
      (4)通过引擎(匹配器)对符合规则的子串进行操作,比如取出。
    针对获取的演示如下:
    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,du jia!";
            System.out.println(str);
            
            String regex = "\b[a-z]{4}\b";//查找四个单词的子字符串
            
            //str = "1237458";
            //String regex = "[1-9]\d{4,14}";
            
            
            //将规则封装成对象。static Pattern compile(String regex) 
            Pattern p = Pattern.compile(regex);
    
           //让正则对象与要操作的字符串关联,返回一个匹配器。Matcher matcher(CharSequence input)。String实现了字符序列接口CharSequence    
            Matcher m = p.matcher(str);
    
           //通过引擎(匹配器)对负荷规则的字符串进行操作,例如引擎对象的方法 matches() 
            
           //System.out.println(m.matches());//其实String类中的matcher方法。用的就是Pattern和Matcher对象来完成的。
                                            //只不过被String的方法封装后,使用起来更为简单。但是功能却很单一。
            
            while(m.find())//将规则作用到字符串上,并进行符合规则的子串查找。
            {
               System.out.println(m.group());//用于获取匹配后的结果    
               System.out.println(m.start()+"...."+m.end());
            }
        }
    } 
     
    正则表达式的应用举例如下:
    练习1:将下列字符串转换成:我要学编程
    到底用四种功能中的哪一个?或者哪几个呢?
    思路方式:
       1.如果只是想知道该字符串是否对与错,使用匹配
       2.想要将已有的字符串替换成其他的字符串,使用替换
       3.想要按照自定的方式将字符串变成多个子串,使用切割。获取规则以外的子串
       4.想要拿到符合需求的字符串子串,使用获取。获取符合规则的子串
    class RegexTest
    {
        public static void main(String[] args)
        {
            Test();
        }
        
        public static void Test()
        {
            String str = "我我...我我...我要..要要...要要...学学学....学学...编编编...编编..程.程程...程...程";
            StringBuilder sb = new StringBuilder();
            
            //先切割(以出现一次或多次的点作为分隔符。特殊字符,对点和反斜杠进行转义)
            String regex1 = "\.+";
            
            String[] arr = str.split(regex1);
            
            for(String s:arr)
            {
               sb.append(s);
            }
            
            //再替换(将一个或多个叠词替换成一个字符)
            String regex2 = "(.)\1+";
            String s1 = "$1";
            System.out.println(sb.toString().replaceAll(regex2,s1));
        }
    }
    练习2:192.68.1.54 102.49.23.013 10.10.10.10 2.2.2.2 8.109.90.30
    将ip地址进行地址段的顺序进行排序
     
    思路:还按照字符串的自然顺序,只要让它们每一段都是3位即可。
    1.按照每一段需要的最多的0进行补齐,那么每一段至少能保证有3位
    2.将每一段只保留3位。那么,所有的ip地址都保留了3位。
    3.切割后,再进行排序
    4.进行最后的一次替换,返回原ip
    public static void ipsort()
        {
            String ip = "192.68.1.54 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(" ");
            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"));
            }
        }
        
        //对qq邮件地址进行校验
        public static void checkMail()
        {
            String mail = "xiayuanquan@qq.com";
            //mail = "1360074459@qq.com";
            
            //String regex = "[a-zA-Z0-9_]+@(qq|QQ)(\.[a-zA-Z]+)+";
            String regex = "\w+@\w+(\.\w+)+";
    
            if(mail.matches(regex))
                System.out.println(mail);
            else
                System.out.println("mail is error!");
        }
        
    }
    练习3:网页爬虫(蜘蛛)
    import java.io.*;
    import java.util.regex.*;
    import java.net.*;
    class RegexTest3
    {
        public static void main(String[] args)throws Exception
        {
            getMails();
            getMails_1();
        }
        
        //获取指定文档中的邮件地址,使用获取功能使用Pattern,Matcher
        public static void getMails()throws Exception
        {
          BufferedReader bufr = new BufferedReader(new FileReader("mails.txt"));    
          
          String line = null;
          String regex = "[a-zA-Z0-9_]+@[a-zA-Z0-9]+(\.[a-zA-Z]+)+";
          //String regex = "\w+@\w+(\.\w+)+";
          
          Pattern p = Pattern.compile(regex);
           
          while((line=bufr.readLine())!=null)
          {
            Matcher m = p.matcher(line);
            
            while(m.find())
            {
               System.out.println(m.group());                
            }
          }
        }    
        
        //从网络上获取邮件地址
        public static void getMails_1()throws Exception
        {
           URL url = new URL("http://www.baidu.com:8080/mail.html");
           
           URLConnection conn = url.openConnection();
           
           BufferedReader bufIn = new BufferedReader(new InputStreamReader(conn.getInputStream()));
           
          String line = null;
          String regex = "\w+@\w+(\.\w+)+";
          
          Pattern p = Pattern.compile(regex);
           
          while((line=bufIn.readLine())!=null)
          {
            Matcher m = p.matcher(line);
            
            while(m.find())
            {
               System.out.println(m.group());                
            }
          }       
        }    
    }
  • 相关阅读:
    Linux 环境下搭建单机版 Redis
    为什么要同时重写equals和hashcode方法
    使用ThreadPoolExecutor 创建线程池,完成并行操作
    一个简单的通过newFixedThreadPool实现多线程案例
    Java 获取对象的所有属性及其对应的值
    分布式id生成方案总结
    使用idea和gradle编译spring5源码
    Pandas中常用的函数使用
    单链表的反转 python实现实例
    kaggle注册中的坑---2018,12.3试过有效
  • 原文地址:https://www.cnblogs.com/XYQ-208910/p/4914330.html
Copyright © 2011-2022 走看看