正则表达式详解

1,616次阅读
一条评论

共计 8139 个字符,预计需要花费 21 分钟才能阅读完成。

概念及语法规则

正则表达式就是一个包含了某些规则的字符串。用来对其他的字符串进行校验,校验其他的字符串是否满足正则表达式的规则。

正则表达式可以用来搜索、编辑或处理文本。

正则表达式并不仅限于某一种语言,但是在每种语言中有细微的差别。

语法规则

  • 特殊字符
    ^:为匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 还会与 "\n""\r"之后的位置匹配。$:为匹配输入字符串的结束位置。如果设置了 RegExp 对象的 Multiline 属性,$ 还会与 "\n""\r"之前的位置匹配。\:转义符
    []:表示一个区间,区间的范围可以自己定义
  • 正则表达式的字符类
    [abc]:代表 a 或者 b,或者 c 字符中的一个。[^abc]:代表除 a,b,c 以外的任何字符。[a-z]:代表 a - z 的所有小写字符中的一个。[A-Z]:代表 A - Z 的所有大写字符中的一个。[0-9]:代表 0-9 之间的某一个数字字符。[a-zA-Z0-9]:代表 a - z 或者 A - Z 或者 0-9 之间的任意一个字符。[a-dm-p]:a 到 d 或 m 到 p 之间的任意一个字符。
  • 正则表达式的逻辑运算符
    &&:并且。多个条件同时满足
    ||:或者。满足其中一个条件即可
  • 正则表达式的预定义字符类在正则中已经定义好的一些有特殊含义的字符,可以直接使用
    ".":匹配任何字符(常用)
    "\\d":任何数字 [0-9] 的简写(常用)
    "\\D":任何非数字 [^0-9] 的简写
    "\\w":单词字符:[a-zA-Z_0-9]的简写 (常用)
    "\\W":非单词字符:[^\w] 的简写
    "\\s":空白字符(空格):[\t\n\x0B\f\r] 的简写
    "\\S":非空白字符:[^\s] 的简写

    注意:在正则表达式中,写 \ 的时候,需要写两个 \,因为 \ 本身是一个转义字符

  • 正则表达式的限定符(数量词)
    X*     : 0次到多次  任意次
    X?     : 0次或 10,1
    X+     : 1次或多次  X>=1
    X{n}     : 恰好 n 次  X== n 次
    X{n,}     : 至少 n 次 X>= n 次
    X{n,m}    : n 到 m 次(n 和 m 都是包含的)   n=<X<=m
  • 正则表达式的分组括号 ( )
    // 示例:校验字符串 "abc" 可以出现任意次
    String regex = "(abc)*";

常用正则表达式

校验数字

// 纯数字
^[0-9]*$
// 正整数
^[1-9]\d*$
// 负整数
^-[1-9]\d*$
// 非零整数(正整数 + 负整数)
^-?[1-9]\d*$
// 非零正整数
^[1-9]\d*$
// 非负整数(正整数 + 0)
^[1-9]\d*|0$    或    ^\d+$
// 非正整数(负整数 + 0)
^-[1-9]\d*|0$

// 正浮点数
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$        
// 负浮点数
^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$    
// 浮点数
^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$
// 非负浮点数(正浮点数 + 0)
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$
// 非正浮点数(负浮点数 + 0)
^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$ 

校验字符

1. 汉字:^[\u4e00-\u9fa5]{0,}$

2. 英文和数字:^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$

3. 长度为 3-20 的所有字符:^.{3,20}$

4. 由 26 个英文字母组成的字符串:^[A-Za-z]+$

5. 由 26 个大写英文字母组成的字符串:^[A-Z]+$

6. 由 26 个小写英文字母组成的字符串:^[a-z]+$

7. 由数字和 26 个英文字母组成的字符串:^[A-Za-z0-9]+$

8. 由数字、26个英文字母或者下划线组成的字符串:^\w+$ 或 ^\w{3,20}$

9. 中文、英文、数字包括下划线:^[\u4E00-\u9FA5A-Za-z0-9_]+$

10. 中文、英文、数字但不包括下划线等符号:^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$

11. 可以输入含有 ^%&',;=?$\" 等字符:[^%&',;=?$\x22]+ 
    
12. 禁止输入含有~ 的字符:[^~\x22]+

特殊需求表达式

1. Email 地址:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$

2. 域名:[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?

3. InternetURL:[a-zA-z]+://[^\s]* 或 ^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$

4. 手机号码:^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$

5. 国内电话号码(0511-4405222021-87888822):\d{3}-\d{8}|\d{4}-\d{7}

6. 身份证号 (15 位、18位数字):^\d{15}|\d{18}$

7. 短身份证号码(数字、字母 x 结尾):^([0-9]){7,18}(x|X)?$ 或 ^\d{8,18}|[0-9x]{8,18}|[0-9X]{8,18}?$

8. 帐号是否合法 (字母开头,允许5-16 字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$

9. 密码 (以字母开头,长度在6~18 之间,只能包含字母、数字和下划线):^[a-zA-Z]\w{5,17}$

10. 强密码 (必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10 之间):^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$

11. 日期格式:^\d{4}-\d{1,2}-\d{1,2}

12. 一年的 12 个月 (0109112):^(0?[1-9]|1[0-2])$

13. 一个月的 31 天(0109131):^((0?[1-9])|((1|2)[0-9])|30|31)$

14. xml 文件:^([a-zA-Z]+-?)+[a-zA-Z0-9]+\\.[x|X][m|M][l|L]$

15. 中文字符的正则表达式:[\u4e00-\u9fa5]

16. 双字节字符(包括汉字在内,可以用来计算字符串的长度(一个双字节字符长度计2,ASCII 字符计1)):[^\x00-\xff] 

17. 空白行的正则表达式(可以用来删除空白行):\n\s*\r 

18. 首尾空白字符的正则表达式(可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式):^\s*|\s*$ 或 (^\s*)|(\s*$)

19. 腾讯 QQ 号:[1-9][0-9]{4,} (腾讯 QQ 号从 10000 开始)

20. 中国邮政编码:[1-9]\d{5}(?!\d) (中国邮政编码为 6 位数字)

21. IP 地址:\d+\.\d+\.\d+\.\d+ (提取 IP 地址时有用)
        
22. 钱的输入格式:钱的表示形式主要有 4 种:"10000.00""10,000.00", 和没有 "分""10000""10,000"
    通用(可为负数、逗号分隔可选、可精确到分)正则表达式:^(0|-?[1-9][0-9]*|(-?[1-9][0-9]{0,2})(,[0-9]{3})*)(.[0-9]{1,2})?$

String 类中和正则表达式相关的方法

// 判断字符串是否满足参数传递的正则表达式的规则。满足:返回 true,不满足:返回 false
boolean matches(String regex)
    
// 根据给定正则表达式的匹配拆分此字符串。
String[] split(String regex)
    
// 使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。
String replaceAll(String regex, String replacement)

示例:

public class Demo07StringRegex {/*
        String replaceAll(String regex, String replacement)
            使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。过滤文章中的关键字
     */
    private static void show04() {String s = "13131sadfdsafjdsafjdlj13j213jlalf;";
        System.out.println("原字符串:"+s);
        // 需求: 使用 replaceAll 方法把字符串中每一个数字替换为 @_@
        String s1 = s.replaceAll("\\d", "@_@");
        System.out.println("替换后的字符串:"+s1);

        // 需求: 使用 replaceAll 方法把字符串中 1 个数字或者连续的数字替换为一个 @_@
        String s2 = s.replaceAll("\\d+","@_@");
        System.out.println("替换后的字符串:"+s2);
    }

    /*
        String[] split(String regex) 根据给定正则表达式的匹配拆分此字符串。参数:
            String regex: 传递正则表达式
            正则表达式中. 代表任意字符
            \\. 使用转义字符, 把有特殊含义的. 转换为普通的.
     */
    private static void show03() {// 根据空格切割字符串
        s = "11    22    33      44";
        String[] arr = s.split("\\s+");// 根据一个空格或者多个空格切割字符串
       
        // 根据. 切割字符串
        String s = "192.168.1.44";
        String[] arr = s.split("\\.");
    }
}

代码示例

字符类 示例

public class Demo02Regex {public static void main(String[] args) {//1. 验证 str 是否以 h 开头,以 d 结尾,中间是 a,e,i,o,u 中某个字符
        String regex = "h[aeiou]d";
        String str = "ead";    //false
        str = "hid";    //true
        str = "hwd";    //false
        // 使用字符串调用 matches 方法根据正则表达式进行校验
        boolean b1 = str.matches(regex);
        System.out.println("b1:" + b1);

        //2. 验证 str 是否以 h 开头,以 d 结尾,中间不是 a,e,i,o,u 中的某个字符
        regex = "h[^aeiou]d";
        str = "wad";    //false
        str = "h2d";    //true
        str = "had";    //false
        boolean b2 = str.matches(regex);
        System.out.println("b2:"+b2);

        //3. 验证 str 是否 a - z 的任何一个小写字符开头,后跟 ad
        regex = "[a-z]ad";
        str = "dad";    //true
        str = "3ad";    //false
        boolean b3 = str.matches(regex);
        System.out.println("b3:"+b3);

        //4. 验证 str 是否以 a - d 或者 m - p 之间某个字符开头,后跟 ad
        regex = "[a-dm-p]ad";
        str = "cad";    //true
        str = "ead";    //false
        boolean b4 = str.matches(regex);
        System.out.println("b4:"+b4);
    }
}

逻辑运算符 示例

public class Demo03Regex {public static void main(String[] args) {String str = "had";//true
        str = "Had";//false
        str = "ead";

        /*
            1. 要求字符串是否是除 a、e、i、o、u 外的其它小写字符开头,后跟 ad
            除 a、e、i、o、u 外:[^aeiou]
            小写字符:[a-z]
            这两个条件同时满足: 并且 &&
         */
        String regex = "[[^aeiou]&&[a-z]]ad";
        boolean b1 = str.matches(regex);
        System.out.println("b1:"+b1);

        /*
            2. 要求字符串是 aeiou 中的某个字符开头,后跟 ad
            "[a||e||i||o||u]ad" 就相当于[aeiou]ad 或运算符是可以省略不写的
         */
        //regex = "[a||e||i||o||u]ad";
        regex = "[aeiou]ad";
        str = "aad";//true
        str = "add";//false
        str = "wad";//false

        boolean b2 = str.matches(regex);
        System.out.println("b2:"+b2);

    }
}

预定义字符 示例

public class Demo04Regex {public static void main(String[] args) {String str = "258";//true
        str = "25x";//false

        //1. 验证 str 是否 3 位数字
        String regex = "[0-9][0-9][0-9]";
        regex = "\\d\\d\\d";
        boolean b1 = str.matches(regex);
        System.out.println("b1:"+b1);

        //2. 验证手机号:1 开头,第二位:3/5/8,剩下 9 位都是 0 - 9 的数字
        regex = "1[358][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]";
        regex = "1[358]\\d\\d\\d\\d\\d\\d\\d\\d\\d";
        str = "13888888888";//true
        str = "23888888888";//false
        str = "138888888881";//false
        str = "138888888a8";//false
        boolean b2 = str.matches(regex);
        System.out.println("b2:"+b2);

        //3. 验证字符串是否以 h 开头,以 d 结尾,中间是任何字符
        regex = "h.d";
        str = "h#d";//true
        str = "h 中 d";//true
        str = "h1d";//true
        str = "h12d";//false
        str = "hd";//false
        boolean b3 = str.matches(regex);
        System.out.println("b3:"+b3);

        /*
            4. 验证 str 是否是:had.
            注意:
              had. 这个字符串中. 不是任意的字符, 就是一个普通的.
              需要使用转义字符把有特殊含义的. 转换为普通的.
         */
        //regex = "had.";
        regex = "had\\.";
        str = "hadA";//false
        str = "had.";//true
        boolean b4 = str.matches(regex);
        System.out.println("b4:"+b4);

    }
}

数量词 示例

public class Demo05Regex {public static void main(String[] args) {String str = ""; //false
        str = "123";//true
        str = "1234";//false
        str = "12a";//false

        //1. 验证 str 是否是三位数字
        String regex = "\\d\\d\\d";
        regex = "\\d{3}";
        boolean b1 = str.matches(regex);
        System.out.println("b1:"+b1);

        //2. 验证 str 是否是多位数字: 数字出现的次数 1 次以上
        regex = "\\d+";
        str = "1231231232132131231";//true
        str = "1";//true
        str = "";//false
        str = "1231a12312";//false
        boolean b2 = str.matches(regex);
        System.out.println("b2:"+b2);

        //3. 验证 str 是否是手机号:1 开头,第二位:3/5/8,剩下 9 位都是 0 - 9 的数字
        regex = "1[358]\\d{9}";
        str = "13888888888";//true
        str = "138888888881";//false
        boolean b3 = str.matches(regex);
        System.out.println("b3:"+b3);

        //4. 验证小数: 必须出现小数点,但是只能出现 1 次
        double d = 1.1;
        d = 0.1;
        d = .1;
        d= 1.;
        //d=.;
        regex = "\\d*\\.\\d*";
        str = "1.1";//true
        str = "0.1";//true
        str = ".1";//true
        str = "1.";//true
        str = "1.aa";//false
        str = "1..1";//false
        str = "11";//false
        boolean b4 = str.matches(regex);
        System.out.println("b4:"+b4);

        //5. 验证小数:小数点可以不出现,也可以出现 1 次
        regex = "\\d*\\.?\\d*";
        str = "11";//true
        str = "1113123.13123123123";//true
        str = "";//true
        str = "a";//false
        str = "11..11";//false
        boolean b5 = str.matches(regex);
        System.out.println("b5:"+b5);

        //6. 验证小数:要求匹配:3、3.、3.14、+3.14、-3.
        regex = "[+-]?\\d+\\.?\\d*";
        str = "3";//true
        str = "3.";//true
        str = "3.14";//true
        str = "+3.14";//true
        str = "-3.";//true
        boolean b6 = str.matches(regex);
        System.out.println("b6:"+b6);

        //7. 验证 qq 号码:1).5--15 位;2). 全部是数字;3). 第一位不是 0 
        regex = "[1-9]\\d{4,14}";
        str = "11111";//true
        str = "1111";//false
        str = "0111111";//false
        str = "1231aaa2";//false
        boolean b7 = str.matches(regex);
        System.out.println("b7:"+b7);
    }
}

分组括号() 示例

public class Demo06Regex {public static void main(String[] args) {// 校验字符串 "abc" 作为一组可以出现任意次
        String regex = "(abc)*";
        String str = "";//true
        str = "abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc";//true
        str = "aabbcc";//false
        boolean b1 = str.matches(regex);
        System.out.println("b1:"+b1);

        str = "DG8FV-B9TKY-FRT9J-99899-XPQ4G";//true
        str = "DG8FV-B9TKY-FRT9J-9989-XPQ4G";//false
        str = "DG8FV-B9TKYFRT9J-99189-XPQ4G";//false

        // 验证这个序列号:分为 5 组,每组之间使用 - 隔开,每组由 5 位 A - Z 或者 0 - 9 的字符组成
        regex = "([A-Z0-9]{5}-){4}[A-Z0-9]{5}";
        boolean b2 = str.matches(regex);
        System.out.println("b2:"+b2);
    }
}

更多资源请  点击这里  关注 TG 频道
正文完
 
lucky
版权声明:本站原创文章,由 lucky 2023-12-17发表,共计8139字。
转载说明:转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(一条评论)