正则表达式

正则表达式简介

Java中有关正则表达式的包的位置

regex包的位置

简单示例

public static void main(String[] args) {
    // 正则表达式
    String numberReg = "^\\d+$";
    // 要匹配的正确和错误的字符串
    String rightNumber = "15927601529";
    String wrongNumber = "159dd2760";
    System.out.println(Pattern.matches(numberReg, rightNumber));    // true
    System.out.println(Pattern.matches(numberReg, wrongNumber));    // false
}

正则表达式基础

正则表达式不仅可以匹配字符,还可以寻找位置。对于没有给定要匹配的字符,则默认是匹配符合条件的位置

匹配字符参考示例

// 驼峰转下划线
public static void underLineToHump() {
    String s = "hump_to_under_line";
    // 匹配大写字母前的位置,这里并没有给定要匹配的字符,所以是匹配位置
    String regExp = "_(\\w)";
    Pattern pattern = Pattern.compile(regExp);
    Matcher matcher = pattern.matcher(s);
    StringBuilder sb = new StringBuilder();
    while (matcher.find()) {
        // appendReplacement方法:sb是一个StringBuffer,replaceContext待替换的字符串,这个方法会把匹配到的内容替换为replaceContext,
        // 并且把从上次替换的位置到这次替换位置之间的字符串也拿到,然后加上这次替换后的结果一起追加到StringBuffer里(假如这次替换是第一次替换,那就是只追加替换后的字符串)。
        matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
    }
    // appendTail方法:sb是一个StringBuffer,这个方法是把最后一次匹配到内容之后的字符串追加到StringBuffer中。
    matcher.appendTail(sb);
    System.out.println("下划线转驼峰:" + sb.toString());
}

匹配位置参考示例

// 驼峰转下划线
public static void humpToUnderLine() {
    String s = "humpToUnderLine";
    // 匹配大写字母前的位置,这里并没有给定要匹配的字符,所以是匹配位置
    String regExp = "(?=[A-Z])";
    Pattern pattern = Pattern.compile(regExp);
    Matcher matcher = pattern.matcher(s);
    String underLine = matcher.replaceAll("_").toLowerCase();
    System.out.println(underLine);
}

常规字符的匹配

字母、数字、汉字、没有特殊定义的标点符号,都属于“常规字符”的定义。

参考代码

public static void normalStrReg(){
        // 定义正则表达式
        String regExp = "abc";
        // 待匹配的字符串
        String s = "acdb,abc,aaa, abc";
        // 得到正则表达式对象
        Pattern pattern = Pattern.compile(regExp);
        // 将匹配结果存储到Matcher对象中
        Matcher matcher = pattern.matcher(s);
        // 可以输出多个结果,find方法内部维护的有指针,每调用一次是移动的
        while (matcher.find()) {
            System.out.println(matcher.group());
        }
    }

简单转义字符的匹配

简单转义字符,制表符\t,回车符和换行符\r,\n,反斜杠\

参考代码

// 简单转义字符
public static void simpleEscapeString() {
    // 定义正则表达式,分别匹配制表符和 “\”
    String regExp1 = "\\t";
    // 字符串中一个\要有两个\\来表示,所以这里需要两个转义符号
    String regExp2 = "\\\\";
    // 待匹配的字符串
    String s = "a\tbc,d\\stat";
    System.out.println(s);
    // 得到正则表达式对象
    Pattern pattern1 = Pattern.compile(regExp1);
    Pattern pattern2 = Pattern.compile(regExp2);
    // 进行匹配
    System.out.println(pattern1.matcher(s).find());
    System.out.println(pattern2.matcher(s).find());
}

某一类特定规律的字符

正向匹配

比如下图中的特殊规律字符
特定规律字符

参考代码

// 匹配特殊规律的字符
    public static void specialChar() {
        // 匹配数字,“+”表示一个或多个
        String regExp1 = "\\d+";
        String s1 = "12zhang_342 wut 1";
        // 获得对象
        Pattern pattern1 = Pattern.compile(regExp1);
        // 获得结果
        Matcher matcher1 = pattern1.matcher(s1);
        System.out.println("多个数字匹配:");
        while (matcher1.find()) {
            System.out.println(matcher1.group());
        }

        // 匹配多个字符
        String regExp2 = "\\w+";
        String s2 = "12zhang_ 342&张 wut 1";
        Pattern pattern2 = Pattern.compile(regExp2);
        Matcher matcher2 = pattern2.matcher(s2);
        System.out.println("多个字符匹配:");
        while (matcher2.find()) {
            System.out.println(matcher2.group());
        }

        // 匹配多个空格、制表符、换页符等空白字符
        String regExp3 = "\\s+";
        String s3 = "12zhang_ 342&张 wut 1";
        Pattern pattern3 = Pattern.compile(regExp3);
        Matcher matcher3 = pattern3.matcher(s3);
        System.out.println("多个空白字符匹配:");
        while (matcher3.find()) {
            System.out.println(matcher3.group());
        }
        // 匹配多个非换行符的字符
        String regExp4 = "helloWorld(.*)helloWorld";
        String s4 = "helloWorld张_12helloWorld";
        Pattern pattern4 = Pattern.compile(regExp4);
        Matcher matcher4 = pattern4.matcher(s4);
        System.out.println("使用.*多个字符匹配:");
        while (matcher4.find()) {
            // 注意这里的group(1)而不是group(),因为是(.*)形式的
            System.out.println(matcher4.group(1));
        }
    }

反向匹配

和正向匹配字符取反

反向匹配

参考代码

// 特殊规律字符反向匹配
public static void specialCharReverse() {
    // 匹配非数字,“+”表示一个或多个
    String regExp1 = "\\D+";
    String s1 = "12zhang_342 wut 1";
    // 获得对象
    Pattern pattern1 = Pattern.compile(regExp1);
    // 获得结果
    Matcher matcher1 = pattern1.matcher(s1);
    System.out.println("匹配非数字:");
    while (matcher1.find()) {
        System.out.println(matcher1.group());
    }

    // 匹配多个非 \w 匹配的字符
    String regExp2 = "\\W+";
    String s2 = "12zhang_ 342&张 wut 1";
    Pattern pattern2 = Pattern.compile(regExp2);
    Matcher matcher2 = pattern2.matcher(s2);
    System.out.println("多个非\\w字符匹配:");
    while (matcher2.find()) {
        System.out.println(matcher2.group());
    }

    // 匹配多个非空白字符
    String regExp3 = "\\S+";
    String s3 = "12zhang_ 342&张 wut 1";
    Pattern pattern3 = Pattern.compile(regExp3);
    Matcher matcher3 = pattern3.matcher(s3);
    System.out.println("多个非空白字符匹配:");
    while (matcher3.find()) {
        System.out.println(matcher3.group());
    }
    // 匹配多个非边界字符,\B和\b匹配的是光标的位置,而非哪一个字符
    String regExp4 = "w\\Bww";
    String s4 = "helloWorld 张_12 hello World! www";
    Pattern pattern4 = Pattern.compile(regExp4);
    Matcher matcher4 = pattern4.matcher(s4);
    System.out.println("多个非边界字符匹配:");
    while (matcher4.find()) {
        System.out.println(matcher4.group());
    }
}

自定义能够匹配某一列字符的表达式

如下图自定义的表达式

自定义表达式

参考代码

// 自定义匹配某一类字符的表达式
public static void customExp() {
    // 自定义表达式匹配,中括号表示匹配里面的一个字符,+表示一个或多个
    String regExp = "[@#&]+";
    String s = "@##&12zhang&_342 #wut 1";
    // 获得对象
    Pattern pattern = Pattern.compile(regExp);
    // 获得结果
    Matcher matcher = pattern.matcher(s);
    System.out.println("自定义匹配@#&:");
    while (matcher.find()) {
        System.out.println(matcher.group());
    }
}

用来匹配特殊位置的字符

这些字符匹配的是位置,而不是哪一个字符

匹配特定位置的字符

参考代码

// 匹配特殊位置的字符,匹配位置而不是字符
public static void positinoRegExp() {
    // 这里匹配的是以数字开头,数字结尾,中间有一个或多个字符
    String regExp = "^\\d.+\\d$";
    String s = "1231zhang_@#123";
    // String s = "1231zhang_@#123a";   // 未匹配成功
    // 获得对象
    Pattern pattern = Pattern.compile(regExp);
    // 获得结果
    Matcher matcher = pattern.matcher(s);
    System.out.println("匹配特殊位置:");
    while (matcher.find()) {
        System.out.println(matcher.group());
    }
    // \b的作用,包括单词的左右边界
    String line = "hello world \t张!";
    System.out.println("原始字符串line:" + line);
    line = line.replaceAll("\\b", "#");
字符串line:" + line);
    line = line.replaceAll("\\b", "#");
    System.out.println("修改之后的字符串line:" + line); // #hello# #world# 	#张#!
}

修改匹配次数的特殊字符

修改匹配次数的字符

参考代码

// 修改匹配次数
public static void matchCountRegExp() {
    // String regExp = "a{2}"; // aa
    // String regExp = "b{2,4}";   // bbbb
    String regExp = "c{5,}";    // cccccc
    String s = "aaabbbbbcccccc";
    Pattern pattern = Pattern.compile(regExp);
    Matcher matcher = pattern.matcher(s);
    while (matcher.find()) {
        System.out.println(matcher.group());
    }
}

匹配特殊字符本身

匹配特殊字符本身

参考代码

// 修改匹配次数
public static void matchCountRegExp() {
    // String regExp = "a{2}"; // aa
    // String regExp = "b{2,4}";   // bbbb
    String regExp = "c{5,}";    // cccccc
    String s = "aaabbbbbcccccc";
    Pattern pattern = Pattern.compile(regExp);
    Matcher matcher = pattern.matcher(s);
    System.out.println("匹配特殊字符本身:");
    while (matcher.find()) {
        System.out.println(matcher.group());
    }
}

正则表达式原理

如下图所示
正则表达式原理浅析

正则表达式进阶

正则表达式子表达式之间的关系

子表达式之间的关系

在获取括号匹配到的内容时,如果使用group()不带参数默认是输出整个字符串,如果传入参数,使用group(1)则表示第一个括号匹配到的内容

参考代码

// 正则表达式子表达式的关系
public static void subRegExp(){
    // 小括号的含义
    String regExp = "https://www.(.*)(\\.com)";
    String s = "https://www.baidu.com";
    Pattern pattern = Pattern.compile(regExp);
    Matcher matcher = pattern.matcher(s);
    System.out.println("()的含义:");
    while (matcher.find()) {
        System.out.println(matcher.group());    // https://www.baidu.com
        // 输出对应括号的匹配的内容
        System.out.println(matcher.group(1));   // baidu
        System.out.println(matcher.group(2));   // .com
    }

    // |的效果,或的含义
    String regExp2 = "zhang|wang";
    String s2 = "zhang li liang wang zhang";
    Pattern pattern2 = Pattern.compile(regExp2);
    Matcher matcher2 = pattern2.matcher(s2);
    System.out.println("|的含义:");
    while (matcher2.find()) {
        System.out.println(matcher2.group());
    }
}

匹配次数的贪婪与非贪婪

匹配次数中的贪婪与非贪婪

上图中缺少了\,应该是(\d)(\w+)和(\d)(\w+)(\d)

贪婪就是尽可能多的去匹配,非贪婪就是尽可能少的去匹配。对于可以多次匹配的字符,默认是贪婪的,可以在后面添加 ”?“ 实现尽可能少的去匹配。但对于上述的 (d)(w+)(d) 形式,(w+) 则是贪婪的,因为只有匹配了(w+)的内容,才可继续匹配后面(d)的内容。

参考代码

// 匹配次数的贪婪与非贪婪
public static void greedOrNoGreedRegExp(){
    // 添加?实现非贪婪
    String regExp = "c{3,}?";
    String s = "aabcccc";
    Pattern pattern = Pattern.compile(regExp);
    Matcher matcher = pattern.matcher(s);
    System.out.println("非贪婪匹配:");
    while (matcher.find()) {
        System.out.println(matcher.group());
    }

    // 这里使用了?,但效果依然是贪婪的,因为只有匹配了(w+)对应的全部内容,才能继续匹配后面(d)的内容
    String regExp2 = "(\\d)(\\w+?)(\\d)";
    String s2 = "zhang li liang wang 1zhang2";
    Pattern pattern2 = Pattern.compile(regExp2);
    Matcher matcher2 = pattern2.matcher(s2);
    System.out.println("关于非贪婪的另一个例子:");
    while (matcher2.find()) {
        System.out.println(matcher2.group());
    }
}

反向引用

反向引用

反向引用就是引用 ”()” 已经匹配的到结果作为正则表达式的一部分

参考代码

// 反向引用,引用”()“已经匹配到的字符串作为正则表达式后续的一部分呢
public static void backReferenceRegExp(){
    // 反向引用,匹配出标签以及标签啊内容
    String regExp = "<(.+)>.*</(\\1)>";
    String s = "<div> zhang </div> <span> <button> button </button> </span>";
    Pattern pattern = Pattern.compile(regExp);
    Matcher matcher = pattern.matcher(s);
    System.out.println("反向引用:");
    while (matcher.find()) {
        System.out.println(matcher.group());
    }
}

正向预搜索匹配与正向预搜索不匹配

正向预搜索匹配,就是搜索到一个待匹配项时,判断后续字符是否符合给定的要求,符合则成功匹配

正向预搜索不匹配,就是搜索到一个待匹配项时,判断后续字符是否符合给定的要求,不符合则成功匹配

参考代码

// 正向预搜索匹配与正向预搜索不匹配
public static void matchOrNoteMatchRegExp() {
    // 正向与搜索,就是搜索到一个待匹配项时,判断后续字符是否符合给定的要求,符合则成功匹配。下面的例子会匹配到一个good前面的java
    String regExp = "java\\s(?=good)";
    String s = "java bad,java good,java and python";
    Pattern pattern = Pattern.compile(regExp);
    Matcher matcher = pattern.matcher(s);
    System.out.println("正向预搜索匹配:");
    while (matcher.find()) {
        System.out.println(matcher.group());    // java
        System.out.println("匹配串后面剩余的所有字符:" + s.substring(matcher.end() - 1));
    }
    // 正向与搜索不匹配
    String regExp1 = "java\\s(?!good)";
    String s1 = "java bad,java good,java and python";
    Pattern pattern1 = Pattern.compile(regExp1);
    Matcher matcher1 = pattern1.matcher(s1);
    System.out.println("正向预搜索不匹配:");
    while (matcher1.find()) {
        System.out.println(matcher1.group());    // java
        System.out.println("匹配串后面剩余的所有字符:" + s1.substring(matcher1.end() - 1));
    }
}

反向预搜索匹配与反向预搜索不匹配

反向预搜索匹配,就是搜索到一个待匹配项时,判断前面的字符是否符合给定的要求,符合则成功匹配

反向预搜索不匹配,就是搜索到一个待匹配项时,判断前面的字符是否符合给定的要求,不符合则成功匹配

参考代码

// 反向预搜索匹配与反向预搜索不匹配
public static void matchOrNoteMatchReverseRegExp() {
    // 反向与搜索,就是搜索到一个待匹配项时,判断前面的字符是否符合给定的要求,符合则成功匹配。下面的例子会匹配到一个good前面的java
    // 小于等于号 ”<=“ 表示左边方向
    String regExp = "(?<=(hello\\s))java";
    String s = "123 1hello java java bad java good java and python";
    Pattern pattern = Pattern.compile(regExp);
    Matcher matcher = pattern.matcher(s);
    System.out.println("反向预搜索匹配:");
    while (matcher.find()) {
        System.out.println(matcher.group());    // 输出hello后的java
        System.out.println("匹配串后面剩余的所有字符:" + s.substring(matcher.end()));
    }
    // 反向与搜索不匹配
    String regExp1 = "(?<!(hello\\s))java";
    String s1 = "123 1hello java java bad java good java and python";
    Pattern pattern1 = Pattern.compile(regExp1);
    Matcher matcher1 = pattern1.matcher(s1);
    System.out.println("反向预搜索不匹配:");
    while (matcher1.find()) {
        System.out.println(matcher1.group());    // java
        System.out.println("匹配串后面剩余的所有字符:" + s1.substring(matcher1.end()));
    }
}

各语言通用规则之汉字匹配

汉字匹配

参考代码

// 各语言通用规则之汉字匹配使用16进制代替
public static void unicodeRegExp() {
    // 汉字匹配,使用16进制编码代替,武汉理工大学的Unicode编码为\u6b66\u6c49\u7406\u5de5\u5927\u5b66\u000d\u000a\u000d\u000a
    // \u6b67是岐
    String regExp = "[\\u6b66-\\u6b67]";
    String s = "hello 武汉理工大学 hello";
    Pattern pattern = Pattern.compile(regExp);
    Matcher matcher = pattern.matcher(s);
    System.out.println("汉字匹配:");
    while (matcher.find()) {
        System.out.println(matcher.group());
    }
}

各语言需要转义的字符列表

需要转义的字符列表

不对子表达式进行捕获

不对子表达式进行捕获

参考代码

// 不捕获子表达式
public static void notMatchSubRegExp() {
    String s = "take me to your heart 123take15 me  武汉理工大学 hello";
    // (?:\d+) 这个表示在使用group(index)捕获匹配内容时,不对该子表达式捕获,不计入表达式的数量中
    String regExp = "(?:\\d+)(.*?)(\\d+)";
    Pattern pattern = Pattern.compile(regExp);
    Matcher matcher = pattern.matcher(s);
    System.out.println("不捕获子表达式:");
    while (matcher.find()) {
        System.out.println(matcher.group(1));    // 输出:take
    }
}

表达式常用属性设置

属性设置

参考代码

// 常用属性设置
public static void usualConfigurationRegExp() {
    String s = "hello world Hello Man HELLO python \n choosepython";
    String regExp = "hello";
    // 设置大小写不敏感
    Pattern pattern = Pattern.compile(regExp,Pattern.CASE_INSENSITIVE);
    // 默认大小写敏感
    // Pattern pattern = Pattern.compile(regExp);
    Matcher matcher = pattern.matcher(s);
    System.out.println("大小写不敏感:");
    while (matcher.find()) {
        System.out.println(matcher.group());
    }

    String s1 = "hello world Hello Man HELLO python\n choosepython";
    String regExp1 = ".*python$";
    // 设置多行匹配
    Pattern pattern1 = Pattern.compile(regExp1,Pattern.MULTILINE);
    // 默认单行匹配
    // Pattern pattern1 = Pattern.compile(regExp1);
    Matcher matcher1 = pattern1.matcher(s1);
    System.out.println("多行匹配:");
    while (matcher1.find()) {
        System.out.println(matcher1.group());
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值