Java正则

元字符

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TestMetaChar {
    // 对元字符进行转义
    private static Pattern pattern = Pattern.compile("myArray\\[0\\]");
    // 匹配 \ (java里\需要用\\表示)
    private static Pattern pattern02 = Pattern.compile("\\\\");
    // 匹配空白字符 \r\n 是 回车+换行 todo 匹配不到?
    private static Pattern pattern03 = Pattern.compile("\r\n\r\n", Pattern.MULTILINE);
    // 简写元字符:
    /* \d 即 [0-9];          \D 即 [^0-9] 【注意:从小到大】*/
    /* \w 即 [a-zA-Z0-9_];   \W 即 [^a-zA-Z0-9_]*/
    /* \s 即 [\f\n\r\t\v];   \S 即 [^\f\n\r\t\v]*/
    // 这个模式匹配不出myArray[10], 需要加上重复次数才行:myArray\[\d+\]
    private static Pattern pattern04 = Pattern.compile("myArray\\[\\d\\]");

    // 这个模式匹配的字符串,必须是6个字符,所以5个纯数字不会匹配(\w\d\w\d\w\d?可以匹配5个纯数字)
    private static Pattern pattern05 = Pattern.compile("\\w\\d\\w\\d\\w\\d");

    public static void main(String[] args) {
        String js = "var myArray = new Array(); \n" +
                "... \n" +
                "if (myArray[0] == 0 || myArray[10] == 10) { \n" +
                "... \n" +
                "}";
        Matcher matcher = pattern.matcher(js);
        if (matcher.find())
            System.out.println(matcher.group());

        String url = "\\home\\ben\\sales";
        Matcher matcher1 = pattern02.matcher(url);
        while (matcher1.find())
            System.out.println(matcher1.group());

        String txt = "101, ben forta " +
                "102, jim james " +
                "       " +
                "103, roberta robertson ";
        Matcher matcher2 = pattern03.matcher(txt);
        while (matcher2.find())
            System.out.println(matcher2.group() + "ok");

        Matcher matcher3 = pattern04.matcher(js);
        while (matcher3.find())
            System.out.println(matcher3.group());

        String txt2 = "11213 a1c2e3 48075 48237 m1b4f2 90046 h1h2h3 123456";
        Matcher matcher4 = pattern05.matcher(txt2);
        while (matcher4.find())
            System.out.println(matcher4.group());
    }
}

// output:
//        myArray[0]
//        \
//        \
//        \
//        myArray[0]
//        a1c2e3
//        m1b4f2
//        h1h2h3
//        123456

匹配次数

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TestRepeatMatch {
    // "\\w+@\\w+.\\w+"模式匹配不了 [email protected]  因为\w是[a-zA-Z0-9_],只能匹配数字字母下划线
    private static Pattern pattern = Pattern.compile("\\w+@\\w+.\\w+");
    private static Pattern pattern04 = Pattern.compile("[\\w.]+@[\\w.]+\\w+");
    //[0-9]+匹配一个或多个数字,等效于\d+  [0-9+]匹配一个数字或者一个+【其实匹配+最好是进行转义\+, 但是在正则的字符集合里面好像可以不转义】
    // + 等效于 {1,}
    private static Pattern pattern02 = Pattern.compile("[0-9]+");
    private static Pattern pattern03 = Pattern.compile("[0-9+]");

    // 如果首字符是. 则不是合法的邮箱,pattern04会匹配出[email protected], 所以改造为pattern05 【* 匹配零次或多次 等价于 {0,}】
    private static Pattern pattern05 = Pattern.compile("\\w+[\\w.]*@[\\w.]+\\w+");
    // ? 匹配0次【false】或1【true】次 等价于{0,1}
    private static Pattern pattern06 = Pattern.compile("https?://[\\w./]+");
    // 精确重复次数
    private static Pattern pattern07 = Pattern.compile("#[\\da-fA-F]{6}");
    // 重复次数区间
    private static Pattern pattern08 = Pattern.compile("\\d{1,2}[/-]\\d{1,2}[/-]\\d{2,4}");
    // 至少重复多少次, 匹配大于100没有的价格
    private static Pattern pattern09 = Pattern.compile("\\$\\d{3,}");

    // 【贪婪模式】
    private static Pattern pattern11 = Pattern.compile("<[Bb]>.*");
    // 防止过度匹配【懒惰模式】
    /**
     *  贪婪模式    懒惰模式
     *  *           *?
     *  +           +?
     *  {n,}        {n,}?
     */
    private static Pattern pattern10 = Pattern.compile("<[Bb]>.*?");

    public static void main(String[] args) {
        String txt = "send personal email to [email protected] or [email protected]. for questions " +
                "about a book use [email protected] or [email protected]. feel free to send" +
                "unsolicited email to [email protected] (wouldn't it be" +
                "nice if it were that simple, huh?). 88 1 + 6";

        Matcher matcher = pattern.matcher(txt);
        while (matcher.find())
            System.out.println(matcher.group());
        System.out.println("===================1====================");

        Matcher matcher02 = pattern02.matcher(txt);
        while (matcher02.find()) {
            System.out.println(matcher02.group());
        }
        System.out.println("===================2====================");

        Matcher matcher03 = pattern03.matcher(txt);
        while (matcher03.find())
            System.out.println(matcher03.group());
        System.out.println("===================3====================");

        Matcher matcher04 = pattern04.matcher(txt);
        while (matcher04.find())
            System.out.println(matcher04.group());
        System.out.println("===================4====================");

        String txt02 = "hello [email protected] is my email address";
        Matcher matcher05 = pattern05.matcher(txt02);
        while (matcher05.find())
            System.out.println(matcher05.group());
        System.out.println("===================5====================");

        String txt03 = "the url is http://www.forta.com/, to connect" +
                "securely use https://www.forta.com/ instead.";
        Matcher matcher1 = pattern06.matcher(txt03);
        while (matcher1.find())
            System.out.println(matcher1.group());
        System.out.println("===================6====================");

        String html = "";
        Matcher matcher2 = pattern07.matcher(html);
        while (matcher2.find())
            System.out.println(matcher2.group());
        System.out.println("===================7====================");

        String txt05 = "4/8/03\n" +
                "10-6-2004\n" +
                "2/2/2\n" +
                "01-01-01\n";
        Matcher matcher3 = pattern08.matcher(txt05);
        while (matcher3.find())
            System.out.println(matcher3.group());
        System.out.println("===================8====================");

        String price = "$496.80 $1290.69 $26.43 $613.42 $7.61 $414.90 $25.00";
        Matcher matcher4 = pattern09.matcher(price);
        while (matcher4.find())
            System.out.println(matcher4.group());
        System.out.println("===================9====================");

        String htm = "i am a B i am a b too";
        Matcher matcher5 = pattern11.matcher(htm);
        while (matcher5.find())
            System.out.println(matcher5.group());
        System.out.println("===================10====================");

        Matcher matcher6 = pattern10.matcher(htm);
        while (matcher6.find())
            System.out.println(matcher6.group());
    }
}

// output:
//          [email protected]
//          [email protected]
//          [email protected]
//          [email protected]
//          [email protected]
//          ===================1====================
//          88
//          1
//          6
//          ===================2====================
//          8
//          8
//          1
//          +
//          6
//          ===================3====================
//          [email protected]
//          [email protected]
//          [email protected]
//          [email protected]
//          [email protected]
//          ===================4====================
//          [email protected]
//          ===================5====================
//          http://www.forta.com/
//          https://www.forta.com/
//          ===================6====================
//          #336633
//          #ffffff
//          ===================7====================
//          4/8/03
//          10-6-2004
//          01-01-01
//          ===================8====================
//          $496
//          $1290
//          $613
//          $414
//          ===================9====================
//          i am a B i am a b too
//          ===================10====================
//          i am a B
//          i am a b too

匹配范围

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TestRangeMatch {

    // pattern会匹配到cat.xls
    private static Pattern pattern = Pattern.compile(".a.\\.xls");
    // pattern02会匹配到usa1.xls
    private static Pattern pattern02 = Pattern.compile("[ns]a.\\.xls");
    // Pattern.MULTILINE表示多行匹配 等同于:Pattern.compile("(?m)^[ns]a.\\.xls")
    private static Pattern pattern03 = Pattern.compile("^[ns]a.\\.xls");
    // 这种用法适合局部忽略大小写的匹配
    private static Pattern pattern04 = Pattern.compile("[Rr]eg[eE]x");

    // [0123456789]可以缩写为[0-9] (从小到大),或者用特殊字符:\\d
    /* - 是特殊的元字符,作为元字符它只能用在[]中*/
    private static Pattern pattern05 = Pattern.compile("^[ns]a[0123456789]\\.xls", Pattern.MULTILINE);

    private static Pattern pattern06 = Pattern.compile("#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]");

    // 取非匹配
    /* ^ 作用范围:集合里的所有字符或字符区间*/
    private static Pattern pattern07 = Pattern.compile("[ns]a[^0-9]\\.xls");

    public static void main(String[] args) {
        String fileLs = "sales1.xls\n" +
                "orders3.xls\n" +
                "sales2.xls\n" +
                "sales.xls\n" +
                "sales3.xls\n" +
                "apac1.xls\n" +
                "europe2.xls\n" +
                "na1.xls\n" +
                "na2.xls\n" +
                "cat.xls\n" +
                "usa1.xls\n" +
                "sam.xls\n" +
                "sa1.xls\n";
        Matcher matcher03 = pattern03.matcher(fileLs);
        while (matcher03.find()) {
            System.out.println(matcher03.group());
        }

        System.out.println("================");

        Matcher matcher = pattern05.matcher(fileLs);
        while (matcher.find()) {
            System.out.println(matcher.group());
        }

        String txt = "The phrase 'regular expression' is often abbreviated as RegEx or regex";
        Matcher matcher1 = pattern04.matcher(txt);
        while (matcher1.find())
            System.out.println(matcher1.group());

        String html = "";
        Matcher matcher2 = pattern06.matcher(html);
        while (matcher2.find())
            System.out.println(matcher2.group());

        Matcher matcher3 = pattern07.matcher(fileLs);
        while (matcher3.find())
            System.out.println(matcher3.group());
    }
}

// output:
//================
//        na1.xls
//        na2.xls
//        sa1.xls
//        RegEx
//        regex
//        #336633
//        #ffffff
//        sam.xls

匹配位置

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TestLocationMatch {

   private static Pattern pattern = Pattern.compile("cat");
   // \s会“消费”空格
   private static Pattern pattern1 = Pattern.compile("\\scat\\s");
   // 使用向后向前查找 定位消费内容
   private static Pattern pattern1_ref = Pattern.compile("(?<=\\s)cat(?=\\s)");
   // \b是单词边界(不会消费空格): \b匹配这样一个位置--位于能够用来构成单词的字符(字母,数字,下划线,也就是与\w匹配的字符)
    // 和一个不能用来构成单词的字符(也就是与\W匹配的字符)之间
    // \b只匹配一个位置,不匹配任何字符,所以"\bcat\b"匹配到的字符串长度是3(c,a,t)
   private static Pattern pattern2 = Pattern.compile("\\bcat\\b");
   private static Pattern pattern3 = Pattern.compile("\\bcap");
   private static Pattern pattern4 = Pattern.compile("cap\\b");

    // ^匹配整个字符串的开始位置 注意:^在正则字符集合起到求非作用
    private static Pattern pattern5 = Pattern.compile("<\\?xml.*?\\?>");
    private static Pattern pattern6 = Pattern.compile("\\s*^<\\?xml.*?\\?>");
    // $匹配整个字符串的结尾位置 例:web页面里,标签后面不应该再有任何内容
    // 可以使用这个模式检查: \s*$

    private static Pattern pattern7 = Pattern.compile("(?m)//.*$");

    public static void main(String[] args) {
        String txt = "the cat scattered his food all over the room";

        String txt2 = "the captain wore his cap and cape proudly as \n" +
                "he sat listening to the recap of how his" +
                "crew saved the men from a capsized vessel";

        System.out.println(matchAll(pattern, txt));
        System.out.println("=====================1========================");
        System.out.println("【有空格】" + matchAll(pattern1, txt));
        System.out.println("=====================2========================");
        System.out.println("【无空格】" + matchAll(pattern1_ref, txt));
        System.out.println("=====================3========================");
        System.out.println("【无空格】" + matchAll(pattern2, txt));
        System.out.println("=====================4========================");
        System.out.println(replaceAll(pattern3, txt2, "@@@"));
        System.out.println("=====================5========================");

        // 如果不对$转义,将会抛出异常:Exception in thread "main" java.lang.IllegalArgumentException: Illegal group reference
        /**
         * https://blog.csdn.net/qq_37502106/article/details/88642840
         * 可以看到这里面对“$”符号和"\\"符号进行了处理。出现以上错误的原因是:String的replaceAll(regex, replacement)方法的第一个参数支持正则表达式,
         * 如果参数replacement中出现符号“$”,会按照$1$2的分组模式进行匹配。当编译器发现“$”后跟的不是整数的时候,就会抛出“Illegal group reference”的异常。
         *
         * 处理办法:用JDK提供的方法,对特殊字符进行处理:
         * replacement = java.util.regex.Matcher.quoteReplacement(replacement);
         * 或者手动转义:\\$\\$\\$
         */
        System.out.println(replaceAll(pattern4, txt2, Matcher.quoteReplacement("$$$")));
        System.out.println("=====================6========================");

        String txt3 = "this xml file has a bad start\n" +
                "   \n" +
                "\n" +
                "";

        System.out.println(matchAll(pattern5, txt3).size() == 1 ? "合格xml" : "不合格xml");
        System.out.println("=====================7========================");
        System.out.println(matchAll(pattern6, txt3).size() == 1 ? "合格xml" : "不合格xml");
        System.out.println("=====================8========================");

        String js = "ar URL= {\n" +
                "            addBatchTemplate: '/myApp/addBatchTemplate',//添加模板\n" +
                "            getBackDeviceTypeList:'/myApp/switcher-device-template/getFrontDeviceTypeList', //获取型号列表\n" +
                "            loadConfig: '/myApp/loadConfig',//post 下发配置\n" +
                "            isInvalidEdit: '/myApp/isInvalidEdit',//权限判断\n" +
                "            isInvalidConfig: '/myApp/isInvalidConfig',//权限判断\n" +
                "            getBatchTemplateInfo:'/myApp/getBatchTemplateInfo', //查询信息\n" +
                "        };\n";
        System.out.println(matchAll(pattern7, js));
    }

    private static List matchAll(Pattern pattern, String source) {
        List matchLs = new ArrayList<>(10);
        Matcher matcher = pattern.matcher(source);
        while (matcher.find())
            matchLs.add(matcher.group());
        return matchLs;
    }

    private static String replaceAll(Pattern pattern, String source, String replaceStr) {
        /**
         * String的replaceAll也是使用正则:Pattern.compile(regex).matcher(this).replaceAll(replacement);
         * 而正则replaceAll的底层使用sb拼接结果: return text.toString(); 所以不会对源字符串造成副作用
         */
        Matcher matcher = pattern.matcher(source);
        return matcher.replaceAll(replaceStr);
    }
}

// output:
//        [cat, cat]
//        =====================1========================
//        【有空格】[ cat ]
//        =====================2========================
//        【无空格】[cat]
//        =====================3========================
//        【无空格】[cat]
//        =====================4========================
//        the @@@tain wore his @@@ and @@@e proudly as
//        he sat listening to the recap of how hiscrew saved the men from a @@@sized vessel
//        =====================5========================
//        the captain wore his $$$ and cape proudly as
//        he sat listening to the re$$$ of how hiscrew saved the men from a capsized vessel
//        =====================6========================
//        合格xml
//        =====================7========================
//        不合格xml
//        =====================8========================
//        [//添加模板, //获取型号列表, //post 下发配置, //权限判断, //权限判断, //查询信息]

子表达式

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TestSubExp {

    //  {2,} 只能匹配  ;;;;; 【因为{2,}只作用于前一个元素】
    private static Pattern pattern = Pattern.compile(" {2,}");
    // 【子表达式限定作用】( ){2,} 可以匹配    ()括起来的就是一个子表达式
    private static Pattern pattern2 = Pattern.compile("( ){2,}");

    // 粗略匹配ip
    private static Pattern pattern3 = Pattern.compile("\\d{1,3}.\\d{1,3}.\\d{1,3}.\\d{1,3}");
    // 【子表达式简化作用】
    private static Pattern pattern4 = Pattern.compile("(\\d{1,3}.){3}\\d{1,3}");

    // "19|20\\d{2}"只会匹配出 19 或 20XX, 因为|把位于它左边和右边的两个部分都作为一个整体看待, todo: |优先级最低?
    // 即:(19)|(20\\d{2}), 所以要匹配出正确的出生年份应该用"(19|20)\\d{2}"
    private static Pattern pattern5 = Pattern.compile("19|20\\d{2}");
    // 【子表达式去提高优先级作用】
    private static Pattern pattern6 = Pattern.compile("(19|20)\\d{2}");

    // 精确匹配ip

    /**
     * 上面用"(\\d{1,3}.){3}\\d{1,3}"粗略匹配ip是有问题的,这个模式会匹配出不合法的ip, 例:666.77.8.999
     * 合法的ip是由4个字节组成(对应逗号隔开的4组数字),一个字节的所表示范围是0~255,即ip中的每组数字都是0~255
     * 正则不能够直接表示数字范围,所以需要将ip取值限制 转成 正则能够表示的规则:
     *
     *  (一)任何一个1位或2位数字      【1~99】  (\d{1,2})
     *  (二)任何一个以1开头的3位数字   【100~199】    (1\d{2})
     *  (三)任何一个以2开头、第2位在0~4的3位数字    【200~249】   (2[0-4]\d)
     *  (四)任何一个以25开头、第3位在0~5的3位数字   【250~255】   (25[0-5])
     *
     *  三四不能用2[0-5][0-5]表达: 因为匹配不到206 207 208 209
     */
    static String quarter = "(\\d{1,2})|(1\\d{2})|(2[0-4]\\d)|(25[0-5])";

    private static Pattern pattern7 = Pattern.compile("(("+quarter+")\\.){3}("+quarter+")");

    /*public static void main(String[] args) {
        Pattern compile = Pattern.compile("2[0-5][0-5]");
        for (int i = 200; i < 299; i++) {
            if (!compile.asPredicate().test(String.valueOf(i))) {
                System.out.println(i);
            }
        }
    }*/

    public static void main(String[] args) {

        String s = "hello, my name is mike jordan, and i am" +
                "the best basketball player, rank No  1";

        System.out.println(replaceAll(pattern, s, "空格"));
        System.out.println("=====================1========================");
        System.out.println(replaceAll(pattern2, s, "空格"));
        System.out.println("=====================2========================");

        String s1 = "ping 12.159.46.200 ... ";
        System.out.println(matchAll(pattern3, s1));
        System.out.println("=====================3========================");
        System.out.println(matchAll(pattern4, s1));
        System.out.println("=====================4========================");

        String s2 = "ID: 042" +
                "SEX: M" +
                "BIRTH: 1967-08-17" +
                "DIE: 2067-08-17" +
                "STATUS: Active";
        System.out.println(matchAll(pattern5, s2));
        System.out.println("=====================5========================");
        System.out.println(matchAll(pattern6, s2));
        System.out.println("=====================6========================");

        String s3 = "illegal ip: 666.77.8.999" +
                "legal ip: 12.159.46.200";
        System.out.println(matchAll(pattern7, s3));
        System.out.println("=====================7========================");
    }

    private static List matchAll(Pattern pattern, String source) {
        List matchLs = new ArrayList<>(10);
        Matcher matcher = pattern.matcher(source);
        while (matcher.find())
            matchLs.add(matcher.group());
        return matchLs;
    }

    private static String replaceAll(Pattern pattern, String source, String replaceStr) {
        /**
         * String的replaceAll也是使用正则:Pattern.compile(regex).matcher(this).replaceAll(replacement);
         * 而正则replaceAll的底层使用sb拼接结果: return text.toString(); 所以不会对源字符串造成副作用
         */
        Matcher matcher = pattern.matcher(source);
        return matcher.replaceAll(replaceStr);
    }
}

// output:
//        hello, my name is mike jordan, and i amthe best basketball player, rank No  1
//        =====================1========================
//        hello, my name is mike jordan, and i amthe best basketball player, rank No空格1
//        =====================2========================
//        [12.159.46.200]
//        =====================3========================
//        [12.159.46.200]
//        =====================4========================
//        [19, 2067]
//        =====================5========================
//        [1967, 2067]
//        =====================6========================
//        [66.77.8.99, 12.159.46.20]
//        =====================7========================

前后查找

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TestLookAround {

    // 匹配标签+内容
    private static Pattern pattern = Pattern.compile("<(title)>(.*)", Pattern.CASE_INSENSITIVE);
    // 匹配内容
    private static Pattern pattern2 = Pattern.compile("(?<=<(title)>).*(?=)", Pattern.CASE_INSENSITIVE);
    // 匹配价格
    private static Pattern pattern3 = Pattern.compile("[0-9.]+");

    private static Pattern pattern4 = Pattern.compile("\\$[0-9.]+");
    // 向后查找
    private static Pattern pattern5 = Pattern.compile("(?<=\\$)[0-9.]+");

    // (?<=<(title)>).*(?=) 用来分隔向后查找和向前查找的()不算子表达式组
    public static void main01(String[] args) {
        String source = "" +
                "BEN FORTA'S HOMEPAGE" +
                "";
        Matcher matcher = pattern2.matcher(source);
        while (matcher.find()) {
            System.out.println(matcher.group(0));
            System.out.println(matcher.group(1));
//            System.out.println(matcher.group(2));
        }

        System.out.println("======");

        // 关于group分层
        Pattern pattern = Pattern.compile("((<(title)>)(.*)())", Pattern.CASE_INSENSITIVE);
        matcher = pattern.matcher(source);
        while (matcher.find()) {
            System.out.println(matcher.group(0));
            System.out.println(matcher.group(1)); // 最外层()
            System.out.println(matcher.group(2)); // 第二层第1个()
            System.out.println(matcher.group(3)); // 第三层第1个()
            System.out.println(matcher.group(4)); // 第二层第2个()
            System.out.println(matcher.group(5)); // 第二层第3个()
            System.out.println(matcher.group(6)); // 第三层第2个()
        }
    }

    public static void main(String[] args) {
        String s = "" +
                "BEN FORTA'S HOMEPAGE" +
                "";
        // 获取匹配的整个结果
        System.out.println(matchAll(pattern, s));
        System.out.println("=====================1========================");
        // 获取匹配的结果中,某个子表达式的匹配部分(子表达式)
        System.out.println(matchTagContent(pattern, s));
        System.out.println("=====================2========================");
        // 前后查找匹配
        System.out.println(matchAll(pattern2, s));
        System.out.println("=====================3========================");

        String s1 = "ABC01: $23.45" +
                "HGG42: $5.31" +
                "CFMX1: $899.00" +
                "XTC99: $69.96" +
                "Total items found: 4";
        System.out.println(matchAll(pattern3, s1));
        System.out.println("=====================4========================");
        System.out.println(matchAll(pattern4, s1));
        System.out.println("=====================5========================");
        System.out.println(matchAll(pattern5, s1));
    }

    private static List matchTagContent(Pattern pattern, String source) {
        List matchLs = new ArrayList<>(10);
        Matcher matcher = pattern.matcher(source);
        while (matcher.find()) {
            // matcher.group(int subExpIdx)
            matchLs.add(matcher.group(2));
        }
        return matchLs;
    }

    private static List matchAll(Pattern pattern, String source) {
        List matchLs = new ArrayList<>(10);
        Matcher matcher = pattern.matcher(source);
        while (matcher.find())
            matchLs.add(matcher.group());
        return matchLs;
    }

    private static String replaceAll(Pattern pattern, String source, String replaceStr) {
        /**
         * String的replaceAll也是使用正则:Pattern.compile(regex).matcher(this).replaceAll(replacement);
         * 而正则replaceAll的底层使用sb拼接结果: return text.toString(); 所以不会对源字符串造成副作用
         */
        Matcher matcher = pattern.matcher(source);
        return matcher.replaceAll(replaceStr);
    }
}

// output:
//        [BEN FORTA'S HOMEPAGE]
//        =====================1========================
//        [BEN FORTA'S HOMEPAGE]
//        =====================2========================
//        [BEN FORTA'S HOMEPAGE]
//        =====================3========================
//        [01, 23.45, 42, 5.31, 1, 899.00, 99, 69.96, 4]
//        =====================4========================
//        [$23.45, $5.31, $899.00, $69.96]
//        =====================5========================
//        [23.45, 5.31, 899.00, 69.96]

回溯引用

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TestBackTraceRef {

    // 匹配一级标题: <[Hh]1>.*?
    private static Pattern pattern = Pattern.compile("

.*?

", Pattern.CASE_INSENSITIVE); // 匹配任意级别标题: <[Hh][1-6]>.*? private static Pattern pattern1 = Pattern.compile(".*?", Pattern.CASE_INSENSITIVE); // 回溯引用去掉不合法标签: <[Hh]([1-6])>.*? 【回溯引用只能用来引用子表达式】 private static Pattern pattern2 = Pattern.compile("<(h[1-6])>.*?", Pattern.CASE_INSENSITIVE); // 回溯引用匹配重复单词 private static Pattern pattern3 = Pattern.compile("\\s(\\w+)\\s\\1"); // 替换中使用回溯 private static Pattern pattern4 = Pattern.compile("(\\w+[\\w.]*@[\\w.]+\\.\\w+)"); private static Pattern pattern5 = Pattern.compile("(\\d{3})-(\\d{3})-(\\d{4})"); public static void main(String[] args) { String html = "" + "

welcome to general expression lesson

" + "

regexp is a good tool to handle string

" + "

you can be a regex master

" + "

this is not valid

" + ""; System.out.println(matchAll(pattern, html)); System.out.println("=====================1========================"); System.out.println(matchAll(pattern1, html)); System.out.println("=====================2========================"); System.out.println(matchAll(pattern2, html)); System.out.println("=====================3========================"); String s = "this is a block of of text," + "several words here are are" + "repeated, and and they" + "should not be"; System.out.println(matchAll(pattern3, s)); System.out.println("=====================4========================"); /** * 在用于替换的字符串中:通过$1,$2引用子表达式匹配结果 */ String s1 = "hi, [email protected] is my email address"; System.out.println(replaceAll(pattern4, s1, "$1")); System.out.println("=====================5========================"); String s2 = "313-555-1234 \n" + "248-555-9999 \n" + "810-555-9000 \n"; System.out.println(replaceAll(pattern5, s2, "($1) $2-$3")); } private static List matchAll(Pattern pattern, String source) { List matchLs = new ArrayList<>(10); Matcher matcher = pattern.matcher(source); while (matcher.find()) matchLs.add(matcher.group()); return matchLs; } private static String replaceAll(Pattern pattern, String source, String replaceStr) { /** * String的replaceAll也是使用正则:Pattern.compile(regex).matcher(this).replaceAll(replacement); * 而正则replaceAll的底层使用sb拼接结果: return text.toString(); 所以不会对源字符串造成副作用 */ Matcher matcher = pattern.matcher(source); return matcher.replaceAll(replaceStr); } } // output: // [

welcome to general expression lesson

] // =====================1======================== // [

welcome to general expression lesson

,

regexp is a good tool to handle string

,

you can be a regex master

,

this is not valid

] // =====================2======================== // [

welcome to general expression lesson

,

regexp is a good tool to handle string

,

you can be a regex master

] // =====================3======================== // [ of of, are are, and and] // =====================4======================== // hi, [email protected] is my email address // =====================5======================== // (313) 555-1234 // (248) 555-9999 // (810) 555-9000

特殊替换

import java.util.regex.Matcher;
        import java.util.regex.Pattern;

public class SpecialReplace {
    public static void main(String[] args) {
        Pattern p = Pattern.compile("java", Pattern.CASE_INSENSITIVE);
        Matcher m = p.matcher("java Java JAVA JAva I love Java and you ?");
        StringBuffer sb = new StringBuffer();
        int index = 1;
        while(m.find()){
            // 当前成功匹配,是偶数次,就替换为小写,否则大写
            m.appendReplacement(sb, (index++ & 1) == 0 ? "java" : "JAVA");
        }
        m.appendTail(sb);//把剩余的字符串加入
        System.out.println(sb);
    }
}

// output:
//          JAVA java JAVA java I love JAVA and you ?

多行匹配

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TestMultilineMatch {

    public static void main(String[] args) {
        String fileLs = "sales1.xls\n" +
                "orders3.xls\n" +
                "sales2.xls\n" +
                "sales.xls\n" +
                "sales3.xls\n" +
                "apac1.xls\n" +
                "europe2.xls\n" +
                "na1.xls\n" +
                "na2.xls\n" +
                "cat.xls\n" +
                "usa1.xls\n" +
                "sam.xls\n" +
                "sa1.xls\n";

        // Pattern.MULTILINE表示多行匹配 等同于:Pattern.compile("(?m)^[ns]a.\\.xls")
        Pattern pattern = Pattern.compile("^[ns]a.\\.xls", Pattern.MULTILINE);
        Matcher matcher = pattern.matcher(fileLs);
        String replaceResult = matcher.replaceAll("多行匹配");
        System.out.println(replaceResult);

        Pattern pattern02 = Pattern.compile("^[ns]a.\\.xls");
        Matcher matcher02 = pattern02.matcher(fileLs);
        String replaceResult02 = matcher02.replaceAll("整串匹配");
        System.out.println(replaceResult02);
    }
}

// output:
//        sales1.xls
//        orders3.xls
//        sales2.xls
//        sales.xls
//        sales3.xls
//        apac1.xls
//        europe2.xls
//        多行匹配
//        多行匹配
//        cat.xls
//        usa1.xls
//        多行匹配
//        多行匹配
//
//        sales1.xls
//        orders3.xls
//        sales2.xls
//        sales.xls
//        sales3.xls
//        apac1.xls
//        europe2.xls
//        na1.xls
//        na2.xls
//        cat.xls
//        usa1.xls
//        sam.xls
//        sa1.xls

贪婪模式

import java.util.regex.MatchResult;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TestGreedyAndLazyMode {
    public static void main(String[] args) {
        String string = "西游记三国演义水浒传";

        Pattern pattern = Pattern.compile("<(book)>.*", Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(string);
        String replaceResult = matcher.replaceFirst("贪婪模式");
        System.out.println(replaceResult);

        Pattern pattern02 = Pattern.compile("<(book)>.*?");
        Matcher matcher02 = pattern02.matcher(string);
        String replaceResult02 = matcher02.replaceFirst("懒惰模式");
        System.out.println(replaceResult02);
    }
}

// output: 
//      贪婪模式
//      懒惰模式三国演义水浒传

纯文本和点

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TestPureTextAndDot {

    private static final Pattern pattern = Pattern.compile("Ben");
    private static final Pattern pattern02 = Pattern.compile("my");
    /**正则默认是大小写敏感的,预编译模式时,可以指定大小写不敏感选项*/
    private static final Pattern pattern03 = Pattern.compile("ben", Pattern.CASE_INSENSITIVE);

    /**.在正则中可以匹配任意一个字符:字符,数字,字母包括.自身【除了换行符】(SQL中有相同功能的是_); */
    private static final Pattern pattern04 = Pattern.compile("sales.");
    private static final Pattern pattern05 = Pattern.compile(".a.\\.xls");

    public static void main(String[] args) {
        String txt = "Hello, my name is Ben. Please visit my01 website at http://www.forta.com/.";
        Matcher matcher = pattern03.matcher(txt);
        while (matcher.find()) {
            System.out.println(matcher.group());
        }

        String fileLs = "sales1.xls\n" +
                        "orders3.xls\n" +
                        "sales2.xls\n" +
                        "sales.xls\n" +
                        "sales3.xls\n" +
                        "apac1.xls\n" +
                        "europe2.xls\n" +
                        "na1.xls\n" +
                        "na2.xls\n" +
                        "sa1.xls\n";
        Matcher matcher1 = pattern04.matcher(fileLs);
        while (matcher1.find()) {
            System.out.println(matcher1.group());
        }

        System.out.println("==================================================================");

        Matcher matcher2 = pattern05.matcher(fileLs);
        while (matcher2.find()) {
            System.out.println(matcher2.group());
        }
    }
}

// output:
//        Ben
//        sales1
//        sales2
//        sales.
//        sales3
//        ==================================================================
//        na1.xls
//        na2.xls
//        sa1.xls

java正则api

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MathcesAndFindDiff {
    public static void main1(String[] args){
        Pattern pattern = Pattern.compile("\\d{3,5}");
        String charSequence = "123-34345-234-00";
        Matcher matcher = pattern.matcher(charSequence);

        //虽然匹配失败,但由于charSequence里面的"123"和pattern是匹配的,所以下次的匹配从位置4开始
        print(matcher.matches());  //虽然整个匹配失败了,但是有部分匹配(123,所以于是重置了下次匹配的位置从3开始),所以后面调用matcher.find()的时候,调用matcher.start()匹配成功是从4开始
        System.out.println("==============================================");
        //测试匹配位置
        matcher.find();
        print(matcher.start());   //如果注释掉前面的print(matcher.matches());,这里会打印出0
        System.out.println("==============================================");

        //使用reset方法重置匹配位置
        matcher.reset();

        //第一次find匹配以及匹配的目标和匹配的起始位置
        print(matcher.find());
        System.out.println("=====================1========================");
        print(matcher.group()+" - "+matcher.start());
        System.out.println("=====================2========================");
        //第二次find匹配以及匹配的目标和匹配的起始位置
        print(matcher.find());
        System.out.println("=====================3========================");
        print(matcher.group()+" - "+matcher.start());
        System.out.println("=====================4========================");

        /**
         * matcher.lookingAt() : Attempts to match the input sequence, starting at the beginning of the
         *      * region, against the pattern (只进行一次前缀匹配)
         */
        //第一次lookingAt匹配以及匹配的目标和匹配的起始位置
        print(matcher.lookingAt());
        System.out.println("=====================5========================");
        print(matcher.group()+" - "+matcher.start());
        System.out.println("=====================6========================");

        //第二次lookingAt匹配以及匹配的目标和匹配的起始位置
        print(matcher.lookingAt());
        System.out.println("=====================7========================");
        print(matcher.group()+" - "+matcher.start());
        System.out.println("=====================8========================");
    }

    private static void print(Object o){
        System.out.println(o);
    }




    public static void main(String[] args) {
        String input = "I dream of engines\nmore engines, all day long";
        System.out.println("INPUT:" + input);
        System.out.println();
        String[] patt = {"engines.more engines", "ines\nmore", "engines$"};
        for (int i = 0; i < patt.length; i++) {
            System.out.println("PATTERN:" + patt[i]);
            boolean found;
            Pattern p1l = Pattern.compile(patt[i]);
            found = p1l.matcher(input).find();
            System.out.println("DEFAULT match " + found);
            // .代表任何符号(DOT ALL),
            Pattern pml = Pattern.compile(patt[i], Pattern.DOTALL | Pattern.MULTILINE);
            found = pml.matcher(input).find();
            System.out.println("Multiline match " + found);
            System.out.println();
        }
    }
}

// output 1:
//        false
//        ==============================================
//        4
//        ==============================================
//        true
//        =====================1========================
//        123 - 0
//        =====================2========================
//        true
//        =====================3========================
//        34345 - 4
//        =====================4========================
//        true
//        =====================5========================
//        123 - 0
//        =====================6========================
//        true
//        =====================7========================
//        123 - 0
//        =====================8========================

// output2:
//        INPUT:I dream of engines
//        more engines, all day long
//
//        PATTERN:engines.more engines
//        DEFAULT match false
//        Multiline match true
//
//        PATTERN:ines
//        more
//        DEFAULT match true
//        Multiline match true
//
//        PATTERN:engines$
//        DEFAULT match false
//        Multiline match true

你可能感兴趣的:(Java正则)