常用正则表达式案例

[]   可接受的字符列表,例如[abcd]表示匹配a、b、c、d中任意一字符
[^]  不可接受的字符列表 [^abc] 除a,b,c之外的任意一个字符,包括数字和特殊符号
[^a-z]表示不匹配a-z中的任意一个字符
[^a-z]{2} {2}表示连续2个字符不是a-z的字符,如A111匹配结果11
[^0-9]表示不匹配0至9中任意一个字符
符号 -  符号 - 连字符 A-Z 任意单个大写字母
符号. 匹配除\n以外的任何字符 a..b表示以a开头,以b结尾,中间包括2个任意字符长度为4的字符串,如aaab,aefb,a35b,a*&b
\\d 匹配单个数字字符,相当于[0-9]
\\d{3} 等价与\\d\\d\\d
\\d{3}(\\d)? 包含3个或4个数字的字符串,如123,8765等
\\D 匹配单个非数字字符,相当于[^0-9] 
\\D(\\d)* 表示以单个非数字字符开头,后接任意个数字字符串,如f、d1234等
\\w 匹配单个数字,大小写字母,下划线,相当于[0-9a-zA-Z_]
\\d{3}\\w{4} 表示以3个数字字符开头的长度为7的字符串
\\W 匹配单个非数字、大消息字母字符,相当于[^0-9a-zA-Z_]
\\W+\\d{2} 表示匹配至少一个非数字,非字母字符开头,2个数字字符结尾的字符串 如#26,#?@67
选择匹配符号| ,表示匹配"|"之前或之后的表达式,如 ab|cd 表示匹配ab或者cd
符号* 表示指定字符重复0次或者n次,如(abc)* ,仅包含任意个abc的字符串,等效与\W*,匹配abc、abcabcabc
符号+ 表示指定字符重复1次或n次(至少一次),m+(abc)*,以至少1个m开头,后接任意个abc的字符串,m,mabc,mabcabc
(?i)abc 表示不区分大小写,匹配abc、Abc等
a(?i)bc或者a(?i)(bc) 表示bc不区分大消息
也可以手动指定不区分大小写
Pattern pattern = Pattern.compile(regStr, Pattern.CASE_INSENSITIVE);
\\s 匹配任何空白字符(空格,制表符等)
\\S 匹配任何非空白字符,和\s刚好相反
.匹配出\n之外的所有字符,如果要匹配.本身,则需要使用\\.

限定符 *+?{}

* 指定的字符重复0次或n次,即0到多;如(abc)匹配abc,abcabc等
+ 指定字符重复1次或n次,如a+(bcd)*匹配至少1个a开头,人一个bcd结尾的字符,如a,abcd,abcdbcd等
?指定字符重复0或1次,如a+bc?表示至少一个a开头,b或者bc结尾的字符串,如ab或者abc,aabc等
{n}只能输入n个字符,如[abcd]{3},表示由a,b,c,d中字母组成的任意长度为3的字符串,如abc,acd,adc等
{n,}至少n次匹配,[abcd]{3,}表示由abcd中字母组成的任意长度不小于3的字符串,如abc,aab等
{n,m}指定至少n个但不多余m个匹配,[abcd]{3,5}表示由abcd中字母组成的任意长度在3到5之间的字符串,如abc,adddd等;

定位符"^" "$" "\b" "\B"

^指定起始字符,如^[0-9]+[a-z]*表示至少一个数字开头,任意个小写字母结尾的字符串,如9a,8等;
$指定结束字符,^[0-9]\\-[a-z]$表示以一个数字开头,后接-,并以a到z任意一个字母结尾
^[0-9]\\-[a-z]+$表示以一个数字开头,后接-,并以a到z任意一个或多个字母结尾
\\b 匹配目标字符串的边界,边界指存在空格或者结尾,如aa\\b匹配kkkaa,kkaa,kk aa等
\\B匹配目标字符串的非边界,边界指开头或者空格,如aa\\B,匹配aadkkklll,aa88,aa uu等

分组

1.非命名捕获

(pattern) 非命名捕获,捕获匹配的字符串,编号为0的第一个捕获是由整个正则表达式模式匹配的文本,其他捕获结果则根据左括号的顺序从1开始自动编号

代码实例

        String content = "huawei nanjing2022 hua0318sheng";
        String regExp = "(\\d\\d)(\\d\\d)";
        Pattern pattern = Pattern.compile(regExp);
        Matcher matcher = pattern.matcher(content);

        while (matcher.find()) {
            System.out.println(matcher.group(0));
            System.out.println(matcher.group(1));
            System.out.println(matcher.group(2));
            System.out.println("------");
        }

输出

2022
20
22
------
0318
03
18
------

2.命名捕获

(?pattern)命名捕获,将匹配的子字符串捕获到一个组名称或编号名称中,用于name的字符串不能包含任何标点符号,并且不能以数字开头,可以使用单引号替代尖括号,如(?'name')

代码实例

        String content = "huawei nanjing2022 hua0318sheng";
        String regExp = "(?\\d\\d)(?\\d\\d)";
        Pattern pattern = Pattern.compile(regExp);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println(matcher.group(0));
            System.out.println(matcher.group(1));
            System.out.println(matcher.group(2));
            System.out.println(matcher.group("group1"));
            System.out.println(matcher.group("group2"));
            System.out.println("------");
        }

输出

2022
20
22
20
22
------
0318
03
18
03
18
------

3.非捕获匹配(?:pattern)

表示匹配pattern,但不捕获匹配的子表达式,对于用or字符"|"组合模式部件的情况很有用,例如huaweinanjing|huaweishenzhen 比huawei(?:nanjing|shenzhen)要繁琐

代码实例

//        String regExp = "huaweinanjing|huaweishenzhen|huaweihangzhou";
        String regExp = "huawei(?:nanjing|shenzhen|hangzhou)";
        String content = "hello huaweinanjing huaweishenzhen huaweihangzhou";
        Pattern pattern = Pattern.compile(regExp);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println(matcher.group(0));
        }

运行结果

huaweinanjing
huaweishenzhen
huaweihangzhou

4.非捕获匹配(?=pattern)

(?=pattern)限定了捕获的范围,如tigger(?=3|5|7)匹配tigger3中的tigger,不匹配tigger2中的tigger

代码实例

        String regExp = "tigger(?=3|5|7)";
        String content = "tigger2 tigger3 tigger5";

        Pattern pattern = Pattern.compile(regExp);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println(matcher.group(0));
        }

输出

tigger // tigger3中的tigger
tigger // tigger5中的tigger

5.非捕获匹配(?!pattern)

该表达式匹配不处于匹配pattern的字符串的起始点的搜索字符串,如tigger(?!3|5|7)不匹配tigger3中tigger,不匹配tigger5中的tigger,不匹配tigger7中的tigger,但可以匹配tigger2中的tigger

代码实例

        String regExp = "tigger(?!3|5|7)";
        String content = "tigger2 tigger3 tigger5";

        Pattern pattern = Pattern.compile(regExp);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println(matcher.group(0));
        }

输出

tigger // tigger2中的tigger

元字符说明

^、$、?(默认非贪婪,如\\d+改成非贪婪匹配\\d+?只匹配一个)

常用场景

1.校验字符串是否是汉字

        // 校验字符串是否是汉字
        String content = "华为";
        String regExp = "^[\u0391-\uffe5]+$";
        Pattern pattern = Pattern.compile(regExp);
        Matcher matcher = pattern.matcher(content);
        if (matcher.find()) {
            System.out.println("是汉字");
        } else {
            System.out.println("不全部是汉字");
        }

2.校验字符串是否是邮政编码

        // 校验字符串是否是邮政编码
        String content = "236566";
        // 1-9开头,紧接着是5位数字结尾
        String regExp = "^[1-9]\\d{5}$";
        Pattern pattern = Pattern.compile(regExp);
        Matcher matcher = pattern.matcher(content);
        if (matcher.find()) {
            System.out.println("是");
        } else {
            System.out.println("否");
        }

3.校验字符串是否是QQ号码

        // 校验字符串是否是QQ号码
        String content = "383754990";
        // 1-9开头,总长度在5到10位的数字
        String regExp = "^[1-9]\\d{4,9}$";
        Pattern pattern = Pattern.compile(regExp);
        Matcher matcher = pattern.matcher(content);
        if (matcher.find()) {
            System.out.println("是");
        } else {
            System.out.println("否");
        }

4.校验字符串是否是手机号码

        // 校验字符串是否是手机号码
        String content = "15276876755";
        // 13,14,15,18开头的11位数字
        String regExp = "^1[3|4|5|8]\\d{9}$";
        Pattern pattern = Pattern.compile(regExp);
        Matcher matcher = pattern.matcher(content);
        if (matcher.find()) {
            System.out.println("是");
        } else {
            System.out.println("否");
        }

5.校验字符串是否是URL

        String content = "https://www.bilibili.com/video/BV11A41157Sa?spm_id_from=333.999.0.0";
        // 1. ^((http|https)://) 匹配https://
        // 2. ([\w-]+\.)+[\w-]+ 匹配www.bilibili.com
        // 3. (/[\w-?=&/%.#]*)? 匹配 /video/BV11A41157Sa?spm_id_from=333.999.0.0
        // [\w-?=&/%.]匹配?,=,&,/,%,.等
        // [.]等价于//. 匹配.本身
        // . 匹配除\n之外的所有字符
        String regExp = "^((http|https)://)?([\\w-]+\\.)+[\\w-]+(\\/[\\w-?=&/%.#]*)?$";
        Pattern pattern = Pattern.compile(regExp);
        Matcher matcher = pattern.matcher(content);
        if (matcher.find()) {
            System.out.println("是");
        } else {
            System.out.println("否");
        }

整体匹配

        String content = "hello nanjing";
        // String regExp  = "hello"; // false
        String regExp  = "hello.* "; // true .*代表任意个字符
        // 整体匹配
        boolean matches = Pattern.matches(regExp, content);
        System.out.println(matches);
注意事项:整体匹配Pattern.matches()与matcher.find()存在一定区别,前者是整体匹配,后者是局部匹配,正则表达式上存在一些区别,不能混用。

整体匹配与局部匹配区别的代码实例

        String content = "hello nanjing";
        String regExp = "hello"; // false
        // String regExp = "hello.* "; // true .*代表任意个字符
        // 整体匹配
        boolean matches = Pattern.matches(regExp, content);
        System.out.println(matches);
        System.out.println("---------------");

        Pattern pattern = Pattern.compile(regExp);
        Matcher matcher = pattern.matcher(regExp);
        if (matcher.find()) {
            System.out.println("存在匹配的串");
        } else {
            System.out.println("不存在匹配的串");
        }

输出:

false
---------------
存在匹配的串

分组、反向引用、捕获

分组:用圆括号组成一个比较复杂的匹配模式,这个圆括号的部分可以看作是一个子表达式,也即一个分组

反向引用:圆括号的内容被捕获后,可以在这个括号后被使用,从而写出一个比较实用的匹配模式,这个我们称为反向引用,这种引用既可以是在正则表达式的内部,也可以是在正则表达式的外部,内部反向引用\分组号,外部反向引用$分组号

捕获:把正则表达式中子表达式/分组匹配的内容保存到内存中以数字编号或显式命名的组里,方便后面引用,从左向右以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推,组0代表的是整个表达式

分组,反向引用,捕获的代码实例

String regExp = "(\\d)\\1";  // 表示连续两位相同的数字,匹配如11、44、55等

String regExp = "(\\d)(\\d)\\2\\1"; // 表示连续的四位数字,1与4位相同,2与3位相同,匹配如1221、3223等

String regExp = "\\d{5}-(\\d)\\1{2}(\\d)\\2{2}(\\d)\\3{2}"; // 匹配连续5位的数字,后面连-,后面连续9位数字,其中每连续3位是相同的情况,如22221-777888999等

口吃去重实例:要求去掉一句话中连续重复的冗余字符,只保留一个即可,如"我....我是中..中.国南南南京人",需要去掉“.”以及连续出现的字符,最终变成“我是中国南京人”

String content = "我....我是中..中.国南南南京人";

// 1.先去掉所有的.
String dotRegExp = "\\.";

Pattern pattern = Pattern.compile(dotRegExp);
Matcher matcher = pattern.matcher(content);
content = matcher.replaceAll("");
// 2.去掉连续重复的字符,只保留一个
// "(.)\\1+"表示匹配任意多个连续字符
// "$1"外部引用,使用第一个字符替换连续重复的字符
Pattern.compile("(.)\\1+").matcher((content)).replaceAll("$1");

String类中使用正则表达式

校验手机号是否138或者139开头,且长度11位

        String content = "13887667805";
        String regExp = "13(?:8|9)\\d{8}";
        if (content.matches(regExp)) {
            System.out.println("合法");
        } else {
            System.out.println("非法");
        }

替换字符串中特定字符串

        // 使用南京替换nanjing
        String content = "nanjing1 是一座美丽的城市,nanjing2拥有悠久的历史,丰厚的文化底蕴...";
        content = content.replaceAll("nanjing(?:1|2)", "南京");
        System.out.println(content);

指定分割符分割字符串

        // 分隔符为+、=、*、-等符号
        String content = "hell-o+nanjing=yuhua+998*77777";
        String[] array = content.split("\\*|-|=|\\+");
        for (String arr : array) {
            System.out.println(arr);
        }

常用场景

验证邮箱合法性

        // .在中[]中表示.本身
        // ^[\w-]+ 表示字符开头,长度1到N位
        // @ 表示@本身
        // ([a-zA-Z0-9]+\\.)+ 表示1到N组"字母数字."的组合,如cn.;com.;edu.cn.等
        // [a-zA-Z0-9]+ 表示字母数字组合长度1到N位不等
        String regExp = "^[\\w-]+@([a-zA-Z0-9]+\\.)+[a-zA-Z0-9]+";
        String content = "[email protected]";
        System.out.println(content.matches(regExp));

解析URL

注意:下面的代码逻辑只具有一定的参考性,具体解析规则要根据实际要求来定

        String content = "https://www.bilibili.com/video/BV11A41157Sa?spm_id_from=333.999.0.0&name=zhangsan";
        // 采用分组方式处理
        String regExp = "([a-zA-Z]+)://([\\w-.]+)(:\\d+|)([/\\w-]*)([?]*)([[\\w_.]*=[\\w_.]*&*]+)";

        Pattern pattern = Pattern.compile(regExp);
        Matcher matcher = pattern.matcher(content);

        while (matcher.find()) {
            System.out.println(matcher.group(0));
            // 协议
            System.out.println(matcher.group(1));
            // 域名
            System.out.println(matcher.group(2));
            // 路径
            System.out.println(matcher.group(4));
            // 参数列表
            System.out.println(matcher.group(6));
        }

常用正则表达式参考

数字 :^[0-9]*$
n位的数字:^\d{n}$
至少n位的数字:^\d{n,}$
m-n位的数字:^\d{m,n}$
零或者非零开头的 数字:^(0|[1-9][1-9]*)$
非零开头的最多带两位小数的数字:^([1-9][0-9*])+(.[0-9]{1-2})?$
带1-2位小数的正数或负数:^(\-)?\d+(\.\d{1,2})?$
正数、负数和小数:^(\-|\+)?\d+(\.\d+)?$
两位小数的正数:^[0-9]+(.[0-9]{2})?$
有1-3位小数的正数:^[0-9]+(.[0-9]{1,3})?$
非零的正整数:^[1-9][0-9]*$或^[1-9]\d*$等
非零的负整数:^-[1-9]\\d*$
非负整数:^\\d+$或者^[1-9]\\d*|0$
非正整数:^-[1-9]\\d*|0$或者^((-\\d+)|(0+))$
非负浮点数:^\\d+(\\.\\d+)?$
非正浮点数:^((-\\d+(\\.\\d+)?)|(0+(\\.0+)?))$
正浮点数:^[1-9]\\d*\\.\\d*|0\\.\\d*[1-9]\\d*$
负浮点数:^-([1-9]\\d*\\.\\d*|0\\.\\d*[1-9]\\d*$
浮点数:^(-?\\d+)(\\.\\d+)?$

校验字符表达式
汉字:^[\u4e00-\u9fa5]+$
英文和数字:^[A-Za-z0-9]+$
长度为3-20的所有字符:^.{3,20}$
中文,英文,数字包括下划线:^[\u4e00-\u9fa5A-Za-z0-9_]+$
可以输入含有^T%,;=?$\等字符:[^T%,;=?$\x22]+
禁止输入含有~的字符[^~\x22]+

你可能感兴趣的:(常用正则表达式案例)