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



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



特点:用一些特定的符号来表示一些代码的操作.这样就简化书写。所以学习正则表达式就是学习一些特殊符号的使用。



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



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



 



具体操作功能:



  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());                
        }
      }       
    }    
}