正则表达式小记

本文详细介绍了正则表达式的概念,包括字面意义字符、字符类、贪婪、逐步、独吞量词、边界比较以及分组与参考。讨论了在Java中使用正则表达式的注意事项,解释了如何创建有效的正则表达式来匹配特定模式,同时阐述了( )、[ ]、{ }在正则表达式中的不同作用和联系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

正则表示式简介

正则表示式基本上包括两种字符:字面意义字符与元字符。

字面意义字符是指按照字面意义比较的字符;

元字符是不按照字面比较,在不同情境有不同意义的字符。

1. 字面意义字符
字符说明
字母或数字比较字母或数字
\\比较\
\0n八进制0n字符(0<=n<=7)
\0nn八进制0nn字符(0<=n<=7)
\0mnn八进制0mnn字符(0<=m<=3,0<=n<=7)
\xhh十六进制0xhh字符
\uhhhh十六进制0xhhh字符
\xh…h十六进制0xh…h字符
\tTab(\u0009)
\n换行(\u000A)
\r返回(\u000D)
\f换页(\u000C)
\a响铃(\u0007)
\eEsc(\u000B)
\cx控制字符x

元字符在正则表示式中具有特殊的意义,如! $ * ( ) + = { } [ ] | \ : . ?等。若要比较这些字符,则必须加上忽略符号\。如果不确定哪些标点符号字符要加忽略符号,可以在每个标点符号前加上\。

使用java字符串撰写正则表示式比较麻烦。
将正则表示式\|放入” “之间时,按照java字符串规定必须忽略\|中的,所以必须写成”\\|”

for(String token : "Justin|Monica|Irene".split("\\|")){
    System.out.println(token);
}

注意:在Java中使用字符串撰写正则表达式时,先写下正则表达式,再在每个\前加上\。

2. 字符类

正则表示式中,多个字符可以分归在一起,成为一个字符类。

一个字符类定义一组字符,其中的任一字符均可出现在输入字符串中以便成功匹配。

归类字符的方式之一是将字符放于[ ]中。

字符类说明
[abc]a或b或c任一字符
[^abc]a、b、c以外的任一字符
[a-zA-Z]a~z或A~Z任一字符
[a-d[m-p]]a~d或m~p任一字符(并集),等于[a-dm-p]
[a-z&&[def]]a~z而且是d、e、f的任一字符(交集),等于[def]
[a-z&&[^bc]]a~z而且不是b或c的任一字符(差集),等于[ad-z]
[a-z&&[^m-p]]a~z而且不是m~p的任一字符,等于[a-lq-z]

字符类中可以再有字符类,把正则表示式想成是语言的话,字符类就像是其中独立的子语言。

预定义字符类说明
.任何字符(与行结束符可能匹配也可能不匹配)
\d数字:[0-9]
\D非数字: [^0-9]
\s空白字符:[ \t\n\x0B\f\r]
\S非空白字符:[^\s]
\w单词字符:[a-zA-Z_0-9]
\W非单词字符:[^\w]
3. 贪婪、逐步、独吞量词
贪婪量词说明
X?X,一次或零次
X*X,零次或多次
X+X,一次或多次
X{n}X,恰好 n 次
X{n,}X,至少 n 次
X{n,m}X,至少 n 次,但是不超过 m 次

贪婪量词
贪婪量词之所以贪婪,是因为看到贪婪量词时,比较器(Matcher)会把剩余文字整个吃掉,再逐步吐出(Back-Off)文字,看看是否符合贪婪量词后的正则表达式。如果吐出部分符合,而吃下的部分也符合贪婪量词就比较成功,结果就是贪婪量词会尽可能地找出长度最长的符合文字。

逐步量词
如果在贪婪量词表示法后加上?,将会成为逐步量词,又称懒惰量词,或非贪婪量词,比较器看到逐步量词时,会一边吃掉剩余文字,一边看看吃下的文字是否符合正则表达式,结果就是逐步量词会尽可能地找出长度最短的符合文字。

独吞量词
如果在贪婪量词表示法后加上+,将会成为独吞量词,比较器看到独吞量词时,会先将剩余文字吃掉,然后看看独吞量词部分是否符合吃下的文字,如果符合就不会再吐出来了。

比较xfooxxxxxxfoo

规则表示式得到符合的文字
.*fooxfooxxxxxxfoo
.*?fooxfoo与xxxxxxfoo
.*+foo
String[] regexs = {".*foo" , ".*?foo" , ".*+foo"};
for(String regex : regexs){
    System.out.println("xfooxxxxxxfoo".replaceAll(regex,"Orz"));
}

//结果:
Orz
OrzOrz
xfooxxxxxxfoo
4. 边界比较

边界比较用来表示文字必须符合指定的边界条件,也就是定位点,因此这类表示式也常称为锚点。

边界比较说明
^一行开头
$一行结尾
\b单词边界
\B非单词边界
\A输入开头
\G前一个符合项目结尾
\Z并非最后终端机的输入结尾
\z输入结尾
5.分组与参考

可以使用()来将正则表示式分组,除了作为子正则表达式之外,还可以搭配量词使用。

例如想要验证电子邮件格式,允许的用户名称开头要是大小写英文字符,之后可搭配数字,正则表示式可以写为\^[a-zA-Z]+\d*;因为@后域名可以有数层,必须是大小写英文字符或数字,正则表示式可写成([a-zA-Z0-9]+.)+,其中使用()群组了正则表示式,之后的+表示这个群组的表示式符合一次或多次,最后要是com结尾,整个结合起来就是^[a-zA-Z]+\d*@([a-zA-Z0-9]+.)+com。

被分组的正则表示式,还可以在稍后回头参考。
在这之前,必须知道分组计数,如果有个规则表示式((A)(b(c))),其中有四个分组,这是遇到的左括号来计数。

(1) ((A)(B (C)))
(2) (A)
(3) (B (C))
(4) (C)

分组回头参考时,是在\后加上分组计数,表示参考第几个分组的比较结果。

( )、[ ]、{ } 的区别与联系

( ) 是为了提取匹配字符串的,表达式中有几个()就有几个相应的匹配字符串。(\s*)表示连续空格的字符串。
[ ] 是定义匹配的字符范围。比如[a-zA-Z0-9]表示相应位置的字符要匹配英文字符和数字。
{ } 一般是用来匹配的长度。比如\s{3}表示匹配三个空格。

圆括号()是组,主要应用在限制多选结构的范围/分组/捕获文本/环视/特殊模式处理。

  1. (abc|bcd|cde),表示这一段是abc、bcd、cde三者之一,顺序也必须一致。
  2. (abc)? 表示这一组要么一起出现,要么不出现,出现那则按顺序出现。
  3. (?:abc)表示找到一样abc的一组,但是不记录,不保存到变量中,否则可以通过变量中,否则可以通过x取第几个括号所匹配道德项,比如:(aaa)(bbb)(ccc)(?:ddd)(eee)可以用$1获取(aaa)匹配到的内容,而$3则获取到了(ccc)匹配到的内容,而$4则获取的是由(eee)匹配到的内容,因为前一对括号没有保存变量。
  4. a(?=bbb)顺序环视 表示a后面必须紧跟3个连续的b。
  5. (?i:xxxx)不区分大小写 (?s:.*)跨行匹配,可以匹配回车符。

方括号是单个匹配 字符集/排除字符集/命名字符集。

  1. [0-3],表示找到一个位置上的字符只能是0到3折四个数字,与(abc|bcd|cde)的作用比较类似,但圆括号可以匹配多个连续的字符,而一对方括号只能匹配单个字符。
  2. [^0-3] 表示找到这个位置上字符只能是除了0到3之外的所有字符。
  3. [:alnum:]代表的是[:alpha:]和[:digit:],即字母和数字;[:digit:]代表的是纯数字。
()和[]有本质的区别

() 内的内容表示的是一个表达式, () 本身不匹配任何东西,只是把括号内的内容作为同一个表达式来处理,例如 (ab){1,3} ,就表示ab一起连续出现最少1次,最多三次。如果没有括号的话,ab{1,3},就表示a 后面紧跟的b出现的最少一次,最多三次。另外,括号在匹配模式中也跟重要。

[]表示匹配字符在[]中并出现一次,并且reshuffle字符写在[]会被当成普通字符来匹配,例如 [(a)] ,会匹配 (、a、)、这三个字符。

写在最后

正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本,在日常生活是是个很方面的工具。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值