JAVA基础(四十)正则表达式

【概述】


/*
 * 正则表达式。
 * 
 * 正则表达式用于操作字符串数据。
 * 通过一些特定的符号来体现的。
 * 所以我们为了掌握正则表达式,必须要学习一些符号。
 * 
 * 虽然简化了,但是阅读性差。 
 *  
 * 
 * 
 */
public class RegexDemo {

    /**
     * @param args
     */
    public static void main(String[] args) {

        
        String qq = "123k4567";
//        checkQQ(qq);
        
        String regex = "[1-9][0-9]{4,14}";//正则表达式。
        
//        boolean b = qq.matches(regex);        
//        System.out.println(qq+":"+b);
        
        
//        String str = "aoooooooob";
//        String reg = "ao{4,6}b";
//        boolean b = str.matches(reg);
//        System.out.println(str+":"+b);
        
        
    }
    
    /*
     * 需求:定义一个功能对QQ号进行校验。
     * 要求:长度5~15. 只能是数字, 0不能开头
     */
    public static void checkQQ(String qq){
        
        int len = qq.length();
        
        if(len>=5 && len<=15){
            
            if(!qq.startsWith("0")){
                try {
                long l = Long.parseLong(qq);
                
                System.out.println(l+":正确");
                }catch(NumberFormatException e){
                    System.out.println(qq+":含有非法字符");
                }
                
            }else{
                System.out.println(qq+":不能0开头");
            }
        }else{
            System.out.println(qq+":长度错误");
        }
        
        
        
    }

}


=================================正则表达式的构造摘要=============================================

【字符】 
x 字符 x                  
\\ 反斜线字符 
\0n 带有八进制值 0 的字符 n (0 <= n <= 7) 
\0nn 带有八进制值 0 的字符 nn (0 <= n <= 7) 
\0mnn 带有八进制值 0 的字符 mnn(0 <= m <= 3、0 <= n <= 7) 
\xhh 带有十六进制值 0x 的字符 hh 
\uhhhh 带有十六进制值 0x 的字符 hhhh 
\t 制表符 ('\u0009') 
\n 新行(换行)符 ('\u000A') 
\r 回车符 ('\u000D') 
\f 换页符 ('\u000C') 
\a 报警 (bell) 符 ('\u0007') 
\e 转义符 ('\u001B') 
\cx 对应于 x 的控制符 
  
【字符类】 
[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,除了 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,作为独立的非捕获组 

=========================================================================================

【正则表达式对字符的常见操作】

public class RegexDemo2 {

    /**
     * @param args
     */
    public static void main(String[] args) {

        /*
         * 正则表达式对字符串的常见操作:
         * 1, 匹配。
         *         其实使用的就是String类中的matches方法。
         * 
         * 2,切割。
         *         其实使用的就是String类中的split方法。 
         * 
         * 3,替换。
         *         其实使用的就是String类中的replaceAll()方法。
         * 
         * 4,获取。
         *         
         */
        
        functionDemo_4();
    }
    
    /*
     * 获取 
     * 将正则规则进行对象的封装。 
     * Pattern p = Pattern.compile("a*b");
     *  //通过正则对象的matcher方法字符串相关联。获取要对字符串操作的匹配器对象Matcher .
      * Matcher m = p.matcher("aaaaab");
      * //通过Matcher匹配器对象的方法对字符串进行操作。
      * boolean b = m.matches();
     * 
     * 
     */
    public  static void functionDemo_4() {
        
        String str = "da jia hao,ming tian bu fang jia!";
        
        String regex = "\\b[a-z]{3}\\b";
        
        //1,将正则封装成对象。
        Pattern p = Pattern.compile(regex);
        //2, 通过正则对象获取匹配器对象。 
        Matcher m = p.matcher(str);
        
        //使用Matcher对象的方法对字符串进行操作。
        //既然要获取三个字母组成的单词 
        //查找。 find();
        System.out.println(str);
        while(m.find()){
            System.out.println(m.group());//获取匹配的子序列
            
            System.out.println(m.start()+":"+m.end());
        }
    }

    /*
     * 替换 
     */
    public static void functionDemo_3() {
        
        String str = "zhangsanttttxiaoqiangmmmmmmzhaoliu";
        
        str = str.replaceAll("(.)\\1+", "$1");//输出zhangsantxiaoqiangmzhaoliu
        
        System.out.println(str);
        
        String tel = "15800001111";//158****1111;
        
        tel = tel.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");//输出158****1111;
        
        System.out.println(tel);
        
    }

    /*
     * 切割。
     * 
     * 组:((A)(B(C))) 
     */
    public static void functionDemo_2(){
        //String str= "zhangsan xiaoqiang zhaoliu";
        //String[] names=str.split(" ");


        //万一空格很多
        //String str= "zhangsan    xiaoqiang    zhaoliu";
        //String[] names=str.split(" +");

        //如果是点,需要转义,这里分两步看,第一步'\\'把‘\’转义成普通的字符,然后再'\.'把点转义成普通的字符'.'

        //String str= "zhangsan.xiaoqiang.zhaoliu";
        //String[] names=str.split("\\.");
            

        String str = "zhangsanttttxiaoqiangmmmmmmzhaoliu";

        //在正则中‘()’相当于java中的一个函数。它会自动编号从1开始,相当于函数名,组零始终代表整个表达式
        //'((A)(B(C)))'代表四个组,第1组是((A)(B(C))) ,第二组\A,第三组(B(C)),第四组是(C)
        String[] names = str.split("(.)\\1+");//str.split("\\.");

        //  '.'第一组的内容,'()'代表函数,'1'代表组的编号1但是要转义成组标号所以要加两个反斜杠,'+'代表至少一次
        for(String name : names){
            System.out.println(name);
        }
        
    }
    /*
     * 演示匹配。 
     */
    public static void functionDemo_1(){
        //匹配手机号码是否正确。 
        String tel = "15800001111";
        //String regex="1[358][0-9]{9}"; 1代表固定第一位是1,[358]代表第二位是这三个数中的一个,[0-9]{9}代表剩余的9位数是0-9;    
        String regex = "1[358]\\d{9}"; //[0-9],可以用"\d"代替但是'\'具有转义的含义,因此需要先把'\'转义成普通的字符。
        boolean b = tel.matches(regex);
        System.out.println(tel+":"+b);
    }
    

}


【练习】
public class RegexTest {

    /**
     * @param args
     */
    public static void main(String[] args) {

        /*
         * 1,治疗口吃:我我...我我...我我我要...要要要要...要要要要..学学学学学...学学编编...编编编编..编..程程...程程...程程程
         * 2,对ip地址排序。 
         * 3,对邮件地址校验。 
         */
        test_3();
    }
    
    //对邮件地址校验。
    public static void test_3() {
        
        String mail = "abc1@sina.com.cn";
        
        String regex = "[a-zA-Z0-9_]+@[a-zA-Z0-9]+(\\.[a-zA-Z]{1,3})+";
        
        regex = "\\w+@\\w+(\\.\\w+)+";//1@1.1
        
        
        
        boolean b = mail.matches(regex);
        
        System.out.println(mail+":"+b);
        
        
    }
    /*
     * 1,治口吃。
     */
    public static void test_1(){
        
        String str = "我我...我我...我我我要...要要要要...要要要要..学学学学学...学学编编...编编编编..编..程程...程程...程程程";
        
        //1,将字符串中.去掉。 用替换。
        str = str.replaceAll("\\.+", "");
        System.out.println(str);
        
        //2,替换叠词。
        str = str.replaceAll("(.)\\1+", "$1");
        System.out.println(str);
        
        
    }
    /*
     * ip地址排序。 
     * 
     * 192.168.10.34 127.0.0.1 3.3.3.3  105.70.11.55
     */
    public static void test_2(){
        
        String ip_str = "192.168.10.34  127.0.0.1  3.3.3.3  105.70.11.55";
        
        
        //1,为了让ip可以按照字符串顺序比较,只要让ip的每一段的位数相同。
        //所以,补零,按照每一位所需做多0进行补充。每一段都加两个0.
        
        ip_str = ip_str.replaceAll("(\\d+)", "00$1");
        System.out.println(ip_str);
        
        //然后每一段保留数字3位。
        ip_str = ip_str.replaceAll("0*(\\d{3})", "$1");
        System.out.println(ip_str);
        
        
        //1,将ip地址切出。
        String[] ips = ip_str.split(" +");
        
        TreeSet<String> ts = new TreeSet<String>();
        
        for(String  ip : ips){
//            System.out.println(ip);
            ts.add(ip);
        }
        
        for(String ip : ts){
            System.out.println(ip.replaceAll("0*(\\d+)", "$1"));
        }
        
    }

}

【爬虫】


/*
 * 网页爬虫:其实就一个程序用于在互联网中获取符合指定规则的数据。 
 * 
 * 爬取邮箱地址。 
 * 
 */
public class RegexTest2 {

    /**
     * @param args
     * @throws IOException 
     */
    public static void main(String[] args) throws IOException {

        
        List<String> list = getMailsByWeb();
        
        for(String mail : list){
            System.out.println(mail);
        }
    }
    
    public static List<String> getMailsByWeb() throws IOException {
        
        //1,读取源文件。
//                BufferedReader bufr = new BufferedReader(new FileReader("c:\\mail.html"));
        
        URL url = new URL("http://192.168.1.100:8080/myweb/mail.html");
        
        BufferedReader bufIn = new BufferedReader(new InputStreamReader(url.openStream()));
                
        //2,对读取的数据进行规则的匹配。从中获取符合规则的数据.
        String mail_regex = "\\w+@\\w+(\\.\\w+)+";
        
        List<String> list = new ArrayList<String>();
        
        
        Pattern p = Pattern.compile(mail_regex);
        
        String line = null;
        
        while((line=bufIn.readLine())!=null){
            
            Matcher m = p.matcher(line);
            while(m.find()){
                //3,将符合规则的数据存储到集合中。
                list.add(m.group());
            }
            
        }
        return list;
    }

    public static List<String>  getMails() throws IOException{
        
        //1,读取源文件。
        BufferedReader bufr = new BufferedReader(new FileReader("c:\\mail.html"));
        
        //2,对读取的数据进行规则的匹配。从中获取符合规则的数据.
        String mail_regex = "\\w+@\\w+(\\.\\w+)+";
        
        List<String> list = new ArrayList<String>();
        
        
        Pattern p = Pattern.compile(mail_regex);
        
        String line = null;
        
        while((line=bufr.readLine())!=null){
            
            Matcher m = p.matcher(line);
            while(m.find()){
                //3,将符合规则的数据存储到集合中。
                list.add(m.group());
            }
            
        }
        return list;
        
    }

}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值