【JAVA】java.util.Pattern的几种模式详细解析

前言

本地的JDK版本是1.8

本篇是我对于Pattern几种模式的一些个人理解,如果大家发现有异议的地方,欢迎大家评论指正

对于其中一些模式,使用了✔️、❌来表示是否能够匹配出结果
✔️ :表示能匹配出内容
❌ :表示不能匹配出内容


1️⃣ CASE_INSENSITIVE

参数描述:
1、忽略大小写,US-ASCII 字符集中的字符大小写不敏感(其实也就是忽略26个英文字母的大小写)
2、想要使UNICODE字符忽略大小写,可以和UNICODE_CASE组合使用(该参数使用说明,请看下面的UNICODE_CASE使用介绍)
3、指定该模式会有轻微的性能损失

🔶测试:

regex为helloworld 匹配 helloworld 和 helloWorld

正则表达式为helloworldhelloworldhelloWorld
使用CASE_INSENSITIVE✔️✔️
不用CASE_INSENSITIVE✔️

在这里插入图片描述

🔶 解释:

当不忽略大小写时,helloWorld 无法被正则表达式helloworld匹配出

🔶 底层代码:

使用了类ASCII里面的转小写方法,将两个字符进行比较

ASCII.toLower(c1) != ASCII.toLower(c2)

2️⃣ UNICODE_CASE

参数描述:
1、忽略Unicode字符大小写 (默认情况下忽略大小写只支持US-ASCII字符)
2、指定此参数,会导致性能下降

大家都知道Unicode也叫做统一码万国码,也就是多国字符的编码
世界上除了26个英文字母之外,还有其他的语言字母是有大小写的(比如希腊字母Ω的小写就是ω,Υ的小写字母是υ),所以需要这个参数

🔶 测试:

regex为helloworldΩ 匹配 helloworldω

正则表达式为helloworldΩhelloworldω
使用 CASE_INSENSITIVE + UNICODE_CASE✔️
只使用CASE_INSENSITIVE

🔶 测试截图:

在这里插入图片描述

🔶 底层代码实现:

int cc1 = Character.toUpperCase(c1);
int cc2 = Character.toUpperCase(c2);
if (cc1 != cc2 && Character.toLowerCase(cc1) !=Character.toLowerCase(cc2))
return false;

3️⃣ COMMENTS

参数描述:
1、忽略空白
2、忽略#后的字符直到行尾

🔶 测试(忽略空白):

regex为hello wo r l d 匹配 helloworld

正则表达式为hello wo r l dhelloworld
不使用COMMENTS
使用COMMENTS✔️

🔶 测试截图:

在这里插入图片描述

🔶 测试(忽略#后面的字符直到行尾):

正则表达式匹配内容:helloworld1
不使用COMMENTS使用COMMENTS
helloworld[0-9]helloworld1helloworld1
hello wo rld [0-9]helloworld1helloworld1
helloworld#[0-9]❌匹配不出结果helloworld
helloworld # [0-9]❌匹配不出结果helloword

🔶 解释:

该参数,会忽略掉表达式中的空格 以及 表达式中#后面的字符

原表达式为使用COMMENTS后表达式变为
hello wo rld [0-9]helloworld[0-9]
helloworld#[0-9]helloworld
helloworld # [0-9]helloworld

4️⃣ MULTILINE

参数描述:
1、在此参数下,正则表达式^$会启用多行模式,默认情况下,正则表达式^$忽略行终止符

🔶 测试:

regex为^world$ 匹配 hello\nworld ,此处包含行终止符\n

正则表达式为^world$匹配内容为:hello\nworld
使用 MULTILINE输出结果:world
不使用MULTILINE

🔶 解释:

如果不使用 MULTILINE ,程序会将hello\nworld 作为一个整体进行匹配; 如果使用 MULTILINE
,程序会根据行终止符号\nhello\nworld分成helloworld
然后匹配第一行的hello,再匹配第二行的world

🔶 测试截图:

在这里插入图片描述


5️⃣ UNIX_LINES

参数描述(使用此参数后):
1、使用.^$时,在此参数下,只能识别\n为行终止符,其他的行终止符无法识别

UNIX_LINES参数,我用MULTILINE参数配合来测试,更容易懂,所以大家先要理解MULTILINE 参数的作用,再来看参数UNIX_LINES

🔶 测试:

测试内容所选模式正则表达式 ^world$原因
匹配结果
hello\u0085worldMULTILINEworld\u0085 是行终止符
MULTILINE+UNIX_LINES❌匹配不出结果\u0085 不再被识别为行终止符
hello\nworldMULTILINEworld\n 是行终止符
MULTILINE+UNIX_LINESworld\nUNIX_LINES模式下唯一被识别的行终止符

🔶 解释:

行终止符是一个或两个字符的序列,用于标记输入字符序列的一行的末尾。

下列都是行终止符(关于行终止符的问题,大家可以参考jdk的Pattern类的api文档):
🔹换行符(换行)字符( ‘\n’ ),
🔹一个回车符,紧跟着一个换行符( “\r\n” ),
🔹独立回车字符( ‘\r’ ),
🔹下一行字符( ‘\u0085’ ),
🔹行分隔符( ‘\u2028’ )
🔹段落分隔符( '\u2029 ’ )

如果UNIX_LINES模式被激活,则\n唯一识别的行终止符是换行符,\u0085不再被识别为行终止符,所以无法匹配出来。

🔶 测试截图:

行终止符为\u0085
在这里插入图片描述

行终止符为\n
在这里插入图片描述


6️⃣ LITERAL

参数描述:
1、在此模式下,输入字符串将被视为文字字符序列。 输入序列中的元字符或转义序列将没有特殊的含义。
2、只有CASE_INSENSITIVEUNICODE_CASE能起到作用,其他都失效

🔶 测试:

测试内容所选模式正则表达式 .elloworld原因
匹配结果
helloworldhelloworld. 可以匹配除了\r\n之外的任何字符,所以可以匹配h
LITERAL❌匹配不出结果在此模式下,.被程序理解为字面意思,只能匹配点,所以无法匹配h
.elloworld.elloworld
LITERAL.elloworld

🔶 测试截图:

在这里插入图片描述


7️⃣ DOTALL

参数描述:
1、.将匹配任何字符,包含行终止符(默认情况下是不匹配行终止符)

此参数在平时还是比较常用的,大多数内容中都会包含行终止符

🔶 测试:

regex为hello(.*)world 匹配 hello\nworld ,此处包含行终止符\n

regex为hello(.*)worldhello\nworld
使用 DOTALL✔️
不使用DOTALL

🔶 测试截图:

在这里插入图片描述


8️⃣ CANON_EQ

参数描述:
1、启用规范等效
2、简单说,就是将一个字符分解,将多个字符组合成一个新的字符,再匹配,称之为标准化(比如光波长度和分子直径的常用计量单位就可以拆分为A\u030A
3、指定此标志可能会造成性能损失


参考资料:
https://www.unicode.org/reports/tr15/tr15-23.html

🔶 测试:

regex为A\u030A 匹配 Å

regex为A\u030A匹配内容:Å
使用 CANON_EQ输出结果:Å
不使用CANON_EQ

🔶 测试截图:

在这里插入图片描述

🔶 底层代码实现:

底层会调用Normalizer 类标准化传入进来的 regex,再进行匹配
Normalizer 类介绍

Normalizer.normalize(pattern, Normalizer.Form.NFD);

9️⃣ UNICODE_CHARACTER_CLASS

参数描述:
1、启用Unicode版本的预定义字符类和POSIX字符类(默认使用的US-ASCII)
2、使用该参数时,会默认启用UNICODE_CASE参数识别大小写
3、指定此标志可能会造成性能损失

某些元字符(\b\d\s\w\B\D\S\W),比如:
\d默认表示的是ASCII中的数字,但在该参数下,它表示Unicode里的数字
\s默认表示的是ASCII中的SPACE,但在该参数下,它表示Unicode里的WHITE_SPACE
\w默认表示的是ASCII中的[A-Za-z0-9_],但在该参数下,它表示Unicode里的字符

🔶 测试:

正则表达式为\w+匹配内容:ABC尤成军
使用UNICODE_CHARACTER_CLASS输出结果:ABC
不使用UNICODE_CHARACTER_CLASS输出结果:ABC尤成军

🔶 解释:

如果不使用UNICODE_CHARACTER_CLASS,那么默认的ASCII中是不会存在中文的,所有\w是不能匹配中文
如果使用UNICODE_CHARACTER_CLASS,Unicode中包含汉字,所以能匹配出尤成军

🔶 测试截图:

在这里插入图片描述


后语

以上是我的一些个人理解,如果大家有任何疑问或者发现有什么不对的地方,可以在下面评论,我会及时修改

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尤成军军军

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值