添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

1、正则表达式概述

正则表达式,又称规则表达式,它的英文叫 Regular Expression ,在代码中常简写为regex、regexp等。它是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。

2、为什么要用正则表达式

首先我们先来做一道题目: 判断一个字符串是否由数字组成 。代码示例如下:

public class Test {
    public static void main(String[] args) {
        //定义字符串
        String str = "123456";
        //转成char数组
        char[] chars = str.toCharArray();
        boolean flag = true;
        //遍历判断
        for (int i = 0; i < chars.length; i++) {
            if (chars[i] < '0' || chars[i] > '9') {
                flag = false;
        if (flag) {
            System.out.println("是由数字组成的字符串!");
        } else {
            System.out.println("不是由数字组成的字符串!");

通过这个例子可以发现,这种写法很轻松就可以得出想要的结果,但是如果我们要判断更加复杂一点的语句就麻烦了,如:电话号码、电子邮箱、网址等。再用这种方式完成就需要写很多的代码,这样就使得代码的可读性降低了。而如果使用正则表达式来匹配就会简洁很多,所以下面我们来学习Java正则表达式的使用。将上面的代码用正则表达式来验证:

public class Test {
    public static void main(String[] args) {
        //定义字符串
        String str = "123456";
        //定义正则表达式;(匹配一次或多次数字);注意:在Java中\(反斜杠)必须要使用转义字符 \\ 来表示
        String regex ="\\d+";
        System.out.println(str.matches(regex));//返回true

3、正则表达式语法大全

注意:在Java正则表达式中\(反斜杠)必须要使用转义字符 \\ 来表示。在JavaScript中,则必须以/^开头,$/结尾。例如:

  • Java:1[358]\\d{9}匹配电话号码为1开头,第二个位置只能为3|5|8,其它位为任意数字
  • JavaScript:/^1[358]\d{9}$/同上
  • {n,} n 是非负整数。至少匹配 n 次。例如,"o{2,}"不匹配"Bob"中的"o",而匹配"foooood"中的所有 o。"o{1,}"等效于"o+"。"o{0,}"等效于"o*"。 {n,m} m 和 n 是非负整数,其中 n <= m。匹配至少 n 次,至多 m 次。例如,"o{1,3}"匹配"fooooood"中的头三个 o。'o{0,1}' 等效于 'o?'。注意:您不能将空格插入逗号和数字之间。 当此字符紧随任何其他限定符(*、+、?、{n}、{n,}、{n,m})之后时,匹配模式是"非贪心的"。"非贪心的"模式匹配搜索到的、尽可能短的字符串,而默认的"贪心的"模式匹配搜索到的、尽可能长的字符串。例如,在字符串"oooo"中,"o+?"只匹配单个"o",而"o+"匹配所有"o"。 匹配除"\r\n"之外的任何单个字符。若要匹配包括"\r\n"在内的任意字符,请使用诸如"[\s\S]"之类的模式。 (pattern) 匹配 pattern 并捕获该匹配的子表达式。可以使用 $0…$9 属性从结果"匹配"集合中检索捕获的匹配。若要匹配括号字符 ( ),请使用"("或者")"。 (?:pattern) 匹配 pattern 但不捕获该匹配的子表达式,即它是一个非捕获匹配,不存储供以后使用的匹配。这对于用"or"字符 (|) 组合模式部件的情况很有用。例如,'industr(?:y|ies) 是比 'industry (?=pattern) 执行正向预测先行搜索的子表达式,该表达式匹配处于匹配 pattern 的字符串的起始点的字符串。它是一个非捕获匹配,即不能捕获供以后使用的匹配。例如,'Windows (?=95|98|NT|2000)' 匹配"Windows 2000"中的"Windows",但不匹配"Windows 3.1"中的"Windows"。预测先行不占用字符,即发生匹配后,下一匹配的搜索紧随上一匹配之后,而不是在组成预测先行的字符后。 (?!pattern) 执行反向预测先行搜索的子表达式,该表达式匹配不处于匹配 pattern 的字符串的起始点的搜索字符串。它是一个非捕获匹配,即不能捕获供以后使用的匹配。例如,'Windows (?!95|98|NT|2000)' 匹配"Windows 3.1"中的 "Windows",但不匹配"Windows 2000"中的"Windows"。预测先行不占用字符,即发生匹配后,下一匹配的搜索紧随上一匹配之后,而不是在组成预测先行的字符后。 food' 匹配"z"或"food"。'(z|food' 匹配"z"或"food"。'(z|f)ood' 匹配"zood"或"food"。 [xyz] 字符集。匹配包含的任一字符。例如,"[abc]"匹配"plain"中的"a"。 [^xyz] 反向字符集。匹配未包含的任何字符。例如,"[^abc]"匹配"plain"中"p","l","i","n"。 [a-z] 字符范围。匹配指定范围内的任何字符。例如,"[a-z]"匹配"a"到"z"范围内的任何小写字母。 [^a-z] 反向范围字符。匹配不在指定的范围内的任何字符。例如,"[^a-z]"匹配任何不在"a"到"z"范围内的任何字符。 匹配一个字边界,即字与空格间的位置。例如,"er\b"匹配"never"中的"er",但不匹配"verb"中的"er"。 非字边界匹配。"er\B"匹配"verb"中的"er",但不匹配"never"中的"er"。 匹配 x 指示的控制字符。例如,\cM 匹配 Control-M 或回车符。x 的值必须在 A-Z 或 a-z 之间。如果不是这样,则假定 c 就是"c"字符本身。 数字字符匹配。等效于 [0-9]。 非数字字符匹配。等效于 [^0-9]。 换页符匹配。等效于 \x0c 和 \cL。 换行符匹配。等效于 \x0a 和 \cJ。 匹配一个回车符。等效于 \x0d 和 \cM。 匹配任何空白字符,包括空格、制表符、换页符等。与 [ \f\n\r\t\v] 等效。 匹配任何非空白字符。与 [^ \f\n\r\t\v] 等效。 制表符匹配。与 \x09 和 \cI 等效。 垂直制表符匹配。与 \x0b 和\cK 等效。 匹配任何字类字符,包括下划线。与"[A-Za-z0-9_]"等效。 与任何非单词字符匹配。与"[^A-Za-z0-9_]"等效。 匹配 n,此处的 n 是一个十六进制转义码。十六进制转义码必须正好是两位数长。例如,"\x41"匹配"A"。"\x041"与"\x04"&"1"等效。允许在正则表达式中使用 ASCII 代码。 匹配 num,此处的 num 是一个正整数。到捕获匹配的反向引用。例如,"(.)\1"匹配两个连续的相同字符。 标识一个八进制转义码或反向引用。如果 n 前面至少有 n 个捕获子表达式,那么 n 是反向引用。否则,如果 n 是八进制数 (0-7),那么 n 是八进制转义码。 标识一个八进制转义码或反向引用。如果 nm 前面至少有 nm 个捕获子表达式,那么 nm 是反向引用。如果 nm 前面至少有 n 个捕获,则 n 是反向引用,后面跟有字符 m。如果两种前面的情况都不存在,则 nm 匹配八进制值 nm,其中 n 和 m 是八进制数字 (0-7)。 当 n 是八进制数 (0-3),ml 是八进制数 (0-7) 时,匹配八进制转义码 nml。 匹配 n,其中 n 是以四位十六进制数表示的 Unicode 字符。例如,\u00A9 匹配版权符号 (©)。

    4、Pattern和Matcher类

    在Java中用来操作正则表达式的是PatternMatcher类,它们都属于java.util.regex 包下:

  • Pattern 类:Pattern类用于创建一个正则表达式,也可以说是创建一个匹配模式,它的构造方法是私有的,所以不可以直接创建,可以通过两个静态方法创建:compile(String regex)compile(String regex,int flags),其中regex是正则表达式,flags为可选模式(如:Pattern.CASE_INSENSITIVE 忽略大小写)。
  • Matcher 类:Matcher 对象是对输入字符串进行解释和匹配操作的引擎。与Pattern 类一样,Matcher 也没有公共构造方法。你需要调用 Pattern 对象的 matcher 方法来获得一个 Matcher 对象。
  • 由于在实际开发工作中,为了方便我们很少直接使用Pattern类或Matcher类,而是使用String类下的方法,所以这里只简单的介绍一下Pattern和Matcher类。

    * 测试Pattern和Matcher public class TestPatternMatcher { public static void main(String[] args) { String str = "1234567abc"; //匹配任何字类字符(包括下划线),至少5次;与"[A-Za-z0-9_]{5,}"等效。 String regex = "\\w{5,}"; //编译正则表达式 Pattern pat = Pattern.compile(regex); //获取Matcher对象 Matcher mat = pat.matcher(str); //进行匹配,结果返回boolean System.out.println(mat.matches());

    关于更多关于Pattern和Matcher的使用可以自行去百度搜索。下面来介绍一下String中如何来处理正则表达式的,String类下用来处理正则表达式的方法如下(常用):

  • 验证:public boolean matches(String regex)
  • 分割:public String[] split(String regex)
  • 替换:public String replaceAll(String regex, String replacement)
  • ①、验证功能:public boolean matches(String regex)

    案例:判断输入的手机号是否为13、15或者18开头的电话号码

    public class Demo {
        public static void main(String[] args) {
            //定义键盘输入流
            Scanner sc = new Scanner(System.in);
            System.out.println("请输入手机好:");
            String s = sc.nextLine();
            //要求:电话号码为1开头,第二个位置只能为3|5|8,其它位为任意数字
            String regex = "1[358]\\d{9}";
            //通过String的matches()方法进行验证
            boolean flag = s.matches(regex);
            System.out.println("flag:" + flag);
    

    注意:String类中的matches(regex)方法其实就是调用了Pattern和Matcher类中的方法。

    ②、分割功能:public String[] split(String regex)

    public class Demo {
        public static void main(String[] args) {
            String str = "Tom:30|Jerry:20|Bob:25";
            String regex = "\\|";
            //Pattern pat = Pattern.compile(regex);
            //String[] arr = pat.split(str);
            String[] arr = str.split(regex);
            for (String s : arr) {
                System.out.println(s);
    

    ③、替换功能:public String replaceAll(String regex,String replacement)

    public class Demo {
        public static void main(String[] args) {
            String str = "12Y34h56dAd7";
            String regex = "[a-zA-Z]+";
            //Pattern pat = Pattern.compile(regex);
            //Matcher mat = pat.matcher(str);
            //System.out.println(mat.replaceAll("-"));
            System.out.println(str.replaceAll(regex, "-"));
    

    5、正则表达式大全(常用)

    以下正则表达式引用自:https://blog.csdn.net/zpz2411232428/article/details/83549502

    一、校验数字的表达式
    1 数字:^[0-9]*$
    2 n位的数字:^\d{n}$
    3 至少n位的数字:^\d{n,}$
    4 m-n位的数字:^\d{m,n}$
    5 零和非零开头的数字:^(0|[1-9][0-9]*)$
    6 非零开头的最多带两位小数的数字:^([1-9][0-9]*)+(.[0-9]{1,2})?$
    7 带1-2位小数的正数或负数:^(\-)?\d+(\.\d{1,2})?$
    8 正数、负数、和小数:^(\-|\+)?\d+(\.\d+)?$
    9 有两位小数的正实数:^[0-9]+(.[0-9]{2})?$
    10 有1~3位小数的正实数:^[0-9]+(.[0-9]{1,3})?$
    11 非零的正整数:^[1-9]\d*$ 或 ^([1-9][0-9]*){1,3}$ 或 ^\+?[1-9][0-9]*$
    12 非零的负整数:^\-[1-9][]0-9"*$ 或 ^-[1-9]\d*$
    13 非负整数:^\d+$ 或 ^[1-9]\d*|0$
    14 非正整数:^-[1-9]\d*|0$ 或 ^((-\d+)|(0+))$
    15 非负浮点数:^\d+(\.\d+)?$ 或 ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$
    16 非正浮点数:^((-\d+(\.\d+)?)|(0+(\.0+)?))$ 或 ^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$
    17 正浮点数:^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ 或 ^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$
    18 负浮点数:^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ 或 ^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$
    19 浮点数:^(-?\d+)(\.\d+)?$ 或 ^-?([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]* 或 ^https://([\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 电话号码("XXX-XXXXXXX"、"XXXX-XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX):^(\(\d{3,4}-)|\d{3.4}-)?\d{7,8}$ 
    6 国内电话号码(0511-4405222、021-87888822):\d{3}-\d{8}|\d{4}-\d{7}
    7 身份证号:
    		15或18位身份证:^\d{15}|\d{18}$
    		15位身份证:^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$
    		18位身份证:^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{4}$
    8 短身份证号码(数字、字母x结尾):^([0-9]){7,18}(x|X)?$ 或 ^\d{8,18}|[0-9x]{8,18}|[0-9X]{8,18}?$
    9 帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
    10 密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线):^[a-zA-Z]\w{5,17}$
    11 强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间):^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$
    12 日期格式:^\d{4}-\d{1,2}-\d{1,2}
    13 一年的12个月(01~09和1~12):^(0?[1-9]|1[0-2])$
    14 一个月的31天(01~09和1~31):^((0?[1-9])|((1|2)[0-9])|30|31)$
    15 钱的输入格式:
    16 1.有四种钱的表示形式我们可以接受:"10000.00" 和 "10,000.00", 和没有 "分" 的 "10000" 和 "10,000":^[1-9][0-9]*$
    17 2.这表示任意一个不以0开头的数字,但是,这也意味着一个字符"0"不通过,所以我们采用下面的形式:^(0|[1-9][0-9]*)$
    18 3.一个0或者一个不以0开头的数字.我们还可以允许开头有一个负号:^(0|-?[1-9][0-9]*)$
    19 4.这表示一个0或者一个可能为负的开头不为0的数字.让用户以0开头好了.把负号的也去掉,因为钱总不能是负的吧.下面我们要加的是说明可能的小数部分:^[0-9]+(.[0-9]+)?$
    20 5.必须说明的是,小数点后面至少应该有1位数,所以"10."是不通过的,但是 "10" 和 "10.2" 是通过的:^[0-9]+(.[0-9]{2})?$
    21 6.这样我们规定小数点后面必须有两位,如果你认为太苛刻了,可以这样:^[0-9]+(.[0-9]{1,2})?$
    22 7.这样就允许用户只写一位小数.下面我们该考虑数字中的逗号了,我们可以这样:^[0-9]{1,3}(,[0-9]{3})*(.[0-9]{1,2})?$
    23 8.1到3个数字,后面跟着任意个 逗号+3个数字,逗号成为可选,而不是必须:^([0-9]+|[0-9]{1,3}(,[0-9]{3})*)(.[0-9]{1,2})?$
    24 备注:这就是最终结果了,别忘了"+"可以用"*"替代如果你觉得空字符串也可以接受的话(奇怪,为什么?)最后,别忘了在用函数时去掉去掉那个反斜杠,一般的错误都在这里
    25 xml文件:^([a-zA-Z]+-?)+[a-zA-Z0-9]+\\.[x|X][m|M][l|L]$
    26 中文字符的正则表达式:[\u4e00-\u9fa5]
    27 双字节字符:[^\x00-\xff] (包括汉字在内,可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1))
    28 空白行的正则表达式:\n\s*\r (可以用来删除空白行)
    29 HTML标记的正则表达式:<(\S*?)[^>]*>.*?|<.*? /> (网上流传的版本太糟糕,上面这个也仅仅能部分,对于复杂的嵌套标记依旧无能为力)
    30 首尾空白字符的正则表达式:^\s*|\s*$或(^\s*)|(\s*$) (可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式)
    31 腾讯QQ号:[1-9][0-9]{4,} (腾讯QQ号从10000开始)
    32 中国邮政编码:[1-9]\d{5}(?!\d) (中国邮政编码为6位数字)
    33 IP地址:\d+\.\d+\.\d+\.\d+ (提取IP地址时有用)
    

    参考链接:https://blog.csdn.net/weixin_43860260/article/details/91417485

    https://www.cnblogs.com/tanghaorong
    本文版权归作者和博客园共有,欢迎转载,但是转载需在博客的合适位置给出原文链接,否则保留追究法律责任的权利。