JAVA正则表达式的使用

正则表达式语法

最简单的正则表达式就是字符串,比如hello world也是一个正则表达式,匹配”hello world”字符串。在这基础上我们加入其他符号表示,以满足我们匹配一定格式的字符串而不是与正则表达式一模一样的字符串,这些符号可以大致分为[]{}(),而其他的一些符号(如.,+,*,\\d等等)其实都可以认为是他们的简写形式。

[]

[]表示匹配一个在[]中包含的任一字符,如[abc]表示匹配a或者b或者c。

  • 可以使用-来表示一个字符区间,[a-c][abc]是等效的;同时可以写多个区间,也可以写完区间后再加入字符,如[a-z0-9A]表示匹配a-z或者0-9或者A中的任一字符;

  • 可以使用^来取补集,即[^a-c]表示匹配除了abc的其他任何字符、[^0-9]表示匹配除了数字的任何字符、[^a]表示匹配除了a的其他任何字符;

  • 一些与[]等效的简写方法:

简写 意义
. 匹配除”\r\n”之外的任何单个字符。
\d 数字字符匹配。等效于 [0-9]。
\D 非数字字符匹配。等效于 [^0-9]。
\s 匹配任何空白字符,包括空格、制表符、换页符等。与 [ \f\n\r\t\v] 等效。
\S 匹配任何非空白字符。与 [^ \f\n\r\t\v] 等效。
\w 匹配任何字类字符,包括下划线。与[A-Za-z0-9_]等效。
\W 与任何非单词字符匹配。与[^A-Za-z0-9_]等效。

另外,由于java中**\\** 表示其他语言的一个\,所以上面的在java中均需要写成\\d、\\D等等。

{}

{}表示对其前面的字符或子表达式匹配的次数。

  • 表达式 意义
    { n} n 是非负整数。正好匹配 n 次。如o{2}匹配两次o
    { n,} n 是非负整数。至少匹配 n 次。
    { n,m} mn 是非负整数,其中 n <= m。匹配至少 n 次,至多 m 次。
  • 表达式 意义
    * 零次或多次匹配前面的字符或子表达式,等效于 {0,}。
    + 一次或多次匹配前面的字符或子表达式, 等效于 {1,}。
    ? 零次或一次匹配前面的字符或子表达式, 等效于 {0,1}。

()

()表示一个捕获组,由此可以使用()来将一个表达式拆分为多个组,实现将一个字符串中需要的信息提取出来。在()中的一开始加入?<name>可以实现对组命名,从而更方便地提取信息。

如(?[A-Za-z]+)表示一个至少由一个字母组成的人名,在获取匹配到的人名时只需要用matcher.group("name")即可得到匹配结果。

JAVA写法

模板

String pattern = "[a-z]+";//正则表达式
Pattern r = Pattern.compile(pattern);//将表达式编译
Matcher matcher = r.matcher(text);//将text字符串作为匹配的字符串
matcher.find();//匹配
value1 = matcher.group("value1");//提取信息

例子

描述

根据时间精度的不同,可能出现以下四种认定为正确的邮件信息格式:

  1. username@domain-yyyy-mm-dd

    例:lethean@buaa.edu.cn-2020-12-02

  2. username@domain-yyyy-mm-dd-hh

    例:myname-lethean@buaa.edu.cn-2020-12-02-15

  3. username@domain-yyyy-mm-dd-hh:mimi

    例:Lethean@buaa.edu.cn-2020-12-02-15:01

  4. username@domain-yyyy-mm-dd-hh:mimi:ss

    例:myname--lethean@buaa.edu.cn-2020-12-20-15:01:20

其中

  • username@domain 为

    邮件发送者的邮箱地址

    • username 为用户名,domain 为域名
  • yyyy-mm-dd / yyyy-mm-dd-hh / yyyy-mm-dd-hh:mimi / yyyy-mm-dd-hh:mimi:ss 为

    发送时间

    • ‘y’ 代表一位年份数字,‘m’ 代表一位月份数字,‘d’ 代表一位日期数字,‘h’ 代表一位小时数字,‘mi’ 代表一位分钟数字,‘s’ 代表一位秒数数字
  • username 为只包含大小写字母、- 的长度不为零的字符串,对于大小写不敏感

  • domain 为只包含大小写字母、数字、. 的长度不为零的字符串,对大小写敏感

写法

String pattern = "(?<username>[A-Za-z-]+)@(?<domain>[A-Za-z0-9.]+)-(?<yyyy>\\d{4})-(?<mm>\\d{2})-(?<dd>\\d{2})(-)?(?<hh>\\d{2})?(:)?(?<mimi>\\d{2})?(:)?(?<ss>\\d{2})?";
        String text = "myname--lethean@buaa.edu.cn-2020-12-20-15:01:20";
        Pattern r = Pattern.compile(pattern);
        Matcher matcher = r.matcher(text);
        if (matcher.find()) { 
            System.out.println("username:"+matcher.group("username"));
            System.out.println("domain:"+matcher.group("domain"));
            System.out.println("yyyy:"+matcher.group("yyyy"));
            System.out.println("mm:"+matcher.group("mm"));
            System.out.println("dd:"+matcher.group("dd"));
            System.out.println("hh:"+matcher.group("hh"));
            System.out.println("mimi:"+matcher.group("mimi"));
            System.out.println("ss:"+matcher.group("ss"));
        }

将text换成4种格式的邮箱均可得到正确结果,不存在的(hh、mimi、ss可能不存在)则为null。

运行结果如下:

username:myname--lethean
domain:buaa.edu.cn
yyyy:2020
mm:12
dd:20
hh:15
mimi:01
ss:20

如果以第3种格式输入,即text为Lethean@buaa.edu.cn-2020-12-02-15:01时,输出如下:

username:Lethean
domain:buaa.edu.cn
yyyy:2020
mm:12
dd:02
hh:15
mimi:01
ss:null

ss因为在该格式中没有所以为空。

例子改

描述

邮件信息输入格式改为:(ss:mimi:hh-)dd-mm-yyyy-username@domain-place

  • 根据时间精度的不同,可能出现以下四种认定为正确的邮件信息格式:

    1. dd-mm-yyyy-username@domain-place

      例:02-12-2020-abc@buaa.edu.cn-Wuhu

    2. hh-dd-mm-yyyy-username@domain-place

      例:03-02-12-2020-abc@buaa.edu.cn-wuhu

    3. mimi:hh-dd-mm-yyyy-username@domain-place

      例:00:03-02-12-2020-abc@buaa.edu.cn-Wuhu

    4. ss:mimi:hh-dd-mm-yyyy-username@domain-place

      例:01:00:03-02-12-2020-abc@buaa.edu.cn-wuhu

place新加的域,表示地点,由英文字母组成,对大小写敏感,即 Beijing 和 beijing 视为不一样的地点

写法

String pattern = "(((?<ss>\\d{2}):)?((?<mimi>\\d{2}):))?((?<hh>\\d{2})-)?(?<dd>\\d{2})-(?<mm>\\d{2})-(?<yyyy>\\d{4})-(?<username>[A-Za-z-]+)@(?<domain>[A-Za-z0-9.]+)-(?<place>[A-Za-z]+)";
String text = "01:11:03-02-12-2020-abc@buaa.edu.cn-wuhu";
Pattern r = Pattern.compile(pattern);
Matcher matcher = r.matcher(text);
if (matcher.find()) { 
    System.out.println("username:"+matcher.group("username"));
    System.out.println("domain:"+matcher.group("domain"));
    System.out.println("yyyy:"+matcher.group("yyyy"));
    System.out.println("mm:"+matcher.group("mm"));
    System.out.println("dd:"+matcher.group("dd"));
    System.out.println("hh:"+matcher.group("hh"));
    System.out.println("mimi:"+matcher.group("mimi"));
    System.out.println("ss:"+matcher.group("ss"));
    System.out.println("place:"+matcher.group("place"));
}

注意前面的(((?<ss>\\d{2}):)?((?<mimi>\\d{2}):))?必须为嵌套的形式,否则匹配时会出现把mimi匹配成ss的错误(因为两者的匹配格式相同,先匹配给了ss,但是嵌套之后就不会出现这种情况)。

运行结果如下:

username:abc
domain:buaa.edu.cn
yyyy:2020
mm:12
dd:02
hh:03
mimi:11
ss:01
place:wuhu

如果将text改为11:03-02-12-2020-abc@buaa.edu.cn-wuhu,输出如下,ss不匹配。

username:abc
domain:buaa.edu.cn
yyyy:2020
mm:12
dd:02
hh:03
mimi:11
ss:null
place:wuhu

本文地址:https://blog.csdn.net/qq_45551930/article/details/114274442