正则表达式

127 篇文章 10 订阅

以下是博主觉得一篇比较OK的教程。 

正则表达式完整教程(略长) - SegmentFault 思否引言亲爱的读者朋友,如果你点开了这篇文章,说明你对正则很感兴趣。想必你也了解正则的重要性,在我看来正则表达式是衡量程序员水平的一个侧面标准。关于正...https://segmentfault.com/a/1190000040988916

/**
         * 一、匹配字符串
         */
        String str = "you[0]";
        //完全匹配:
        List<String> all01 = ReUtil.findAll("you", str, 0);
        System.out.println(all01);

        //完全匹配:符号转义
        List<String> all02 = ReUtil.findAll("you\\[0\\]", str, 0);
        System.out.println(all02);

        //模糊匹配:横向【ab后出现1~3个c结尾d】 注意:出现5到无限个{5,}
        List<String> all03 = ReUtil.findAll("abc{1,3}d", "abcccd", 0);
        System.out.println(all03);

        //模糊匹配:纵向【a出现后 中间是1或2 结尾是c】
        List<String> all04 = ReUtil.findAll("a[12]c", "abc a1c a2c a100c", 0);
        System.out.println(all04);

        //模糊匹配:横向纵向【a出现后  中间是0~3个数字 结尾是c】
        List<String> all05 = ReUtil.findAll("a[\\d]{0,3}c", "ac abc a1c a2c a100c", 0);
        System.out.println(all05);

        //范围简写:字符范围:a-zA-Z0-9...
        List<String> all06 = ReUtil.findAll("a[0-9]{0,3}c", "ac abc a1c a2c a100c", 0);
        System.out.println(all06);

        //排除:a出现后,中间出现一个单位,但不能是数字,结尾是c
        List<String> all07 = ReUtil.findAll("a[^0-9]c", "ac abc a1c a2c a100c", 0);
        System.out.println(all07);

        //贪婪(默认):尽可能多的匹配,即,中间尽可能匹配6个字符,然后5个...直到匹配为止
        List<String> all08 = ReUtil.findAll("a[a-z]{2,6}", "a ab abc abcd abcde", 0);
        System.out.println(all08);

        //惰性(加上?):尽可能少的匹配,即,中间尽可能匹配2个字符,然后3个...直到匹配为止
        List<String> all09 = ReUtil.findAll("a[a-z]{2,6}?", "a ab abc abcd abcde", 0);
        System.out.println(all09);

        //并行(默认是惰性啊,前一个匹配到了后一个不再参与):两个正则表达式 用|隔开
        List<String> all10 = ReUtil.findAll("a[a-z]|a[0-9]", "a ab abc abcd abcde a1 a2 a3", 0);
        System.out.println(all10);

        //分组:即将多个字符当做一个单位进行匹配,比如匹配连续的ab
        List<String> all11 = ReUtil.findAll("(ab)+", "a ab aba abab ababab", 0);
        System.out.println(all11);

        // ?={0,1} 0或1次; +={1,} 1到无限次; *={0,} 0到无限次

        /**
         * 案例:content:<div id="container" class="main"></div>
         * 如何匹配出 id=”container“,其中container是不确定的
         * 1. id="[a-z]*"    这种形式表示,双引号中间可以有0-无限个字符;可以匹配到,但是container可能含有数字特殊字符等等
         * 2. id=".*"        这种形式表示,双引号中间可以有无限个单位,其中引号“ 也会被当做一个单位匹配,默认是贪婪模式,尽可能多的匹配,直到最后一个引号为止,所以结果是:id="container" class="main"
         * 3. id=".*?"       这是第二种的惰性形式,尽可能少的匹配,匹配到第一个就停止。(效率低)
         * 4. id="[^"]*"     这种形式表示,双引号中间除了引号都可以。
         */
        List<String> all12 = ReUtil.findAll("id=\"[a-z]*\"", "<div id=\"container\" class=\"main\"></div>", 0);
        System.out.println(all12);

        /**
         * 二、匹配位置
         */
        // 匹配字符的开头和结尾 ^表示开头位置,$表示结尾位置:这里注意^表示开头位置,[^xxx]表示取反
        String s = "Hello World";
        // 案例:在字符串开头和结尾加上#
        String e = s.replaceAll("^|$", "#");
        System.out.println(e);

        // \b单词边界 \B非单词边界,即\b表示每个的单词的开头和结尾,\B则相反,表示非单词开头和结尾

        String b = s.replaceAll("\\b", "#");
        //#Hello# #World#
        System.out.println(b);

        String bb = s.replaceAll("\\B", "#");
        //H#e#l#l#o W#o#r#l#d
        System.out.println(bb);

        //(?=p)和(?!p) 表示p前面的位置、非p前面的位置

        //将所有不是以左括号结尾的avg单词替换成max
        //avg[^(] 可以匹配到所有非左括号结尾的avg单词,但是包括了非左括号。
        //avg(?=[^(]) 直接匹配到avg进行替换
        
        /**
         * 三、提取数据
         */
        // 匹配日期格式
        String date = "2017-06-12";
        List<String> all13 = ReUtil.findAll("\\d{4}-\\d{2}-\\d{2}", date, 0);
        //2017-06-12
        System.out.println(all13);
        //但是我们现在需要 2017 06 12 这三组数据,怎么办呢?
        //2017-06-12
        Set<String> all14 = ReUtil.findAll("(\\d{4})-(\\d{2})-(\\d{2})", date, 0, new HashSet<>());
        //2017
        Set<String> all15 = ReUtil.findAll("(\\d{4})-(\\d{2})-(\\d{2})", date, 1, new HashSet<>());
        //06
        Set<String> all16 = ReUtil.findAll("(\\d{4})-(\\d{2})-(\\d{2})", date, 2, new HashSet<>());
        //12
        Set<String> all17 = ReUtil.findAll("(\\d{4})-(\\d{2})-(\\d{2})", date, 3, new HashSet<>());
        //2017-06-12, 2017, 06, 12
        List<String> all18 = ReUtil.getAllGroups(PatternPool.get("(\\d{4})-(\\d{2})-(\\d{2})", Pattern.DOTALL), date);

案例一:获取特定标签中的内容(贪婪匹配)

public static void main(String[] args) {
        String s = "<pre><code class=\"language-java\"> <br/>新中国 <br/> </code></pre><p><br></p><p><br></p>";
        /**
         * 目标:提取出<code></code>标签中的数据,即: <br/>新中国 <br/>
         * 1.<code>.*</code>;可以定位基础标签,但是有class属性就没办法了
         * 2.<code.*>.*</code>;可以定位有class属性的code标签,但是因为标签内容中存在>,会引发贪婪
         * 3.<code.*?>.*</code>;使用惰性定位,但是无法精确提取想要的数据
         * 4.<code.*?>(.*)</code>;通过分组可以拿到标签内的数据了。
         */
        List<String> allGroups = ReUtil.getAllGroups(PatternPool.get("<code.*?>(.*)</code>", Pattern.DOTALL), s);
        for (String allGroup : allGroups) {
            System.out.println(allGroup);
        }

    }

案例二:获取多个特定标签内容(惰性匹配)

re.findall('<record>[\s\S]*?/record>',html_str)

案例三:匹配空
 

re.findall('^(?![\s\S])',html_str)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

文子阳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值