Java学习记录06

正则表达式匹配规则

对于正则表达式来说,它只能精确匹配字符串。

例如:正则表达式“abc",只能匹配”abc",不能匹配“ab","Abc","abcd"等其他字符串。

如果想匹配非ASCII字符,例如中文,那么就用\u####的十六进制表示,例如: a\u548cc匹配的是字符串"a和c",中文字符和的Unicode编码是548c

基本规则

匹配任意字符

我们可以用 . 匹配一个任意字符。

例如,正则表达式a.c中间的点可以匹配任意一个字符,它可以匹配abc,a&c,acc等,但是不能匹配aca&&c,因为 . 匹配一个字符且仅限一个字符。

匹配数字

如果我们只想匹配0~9这样的数字,可以用\d匹配。

例如:00\d可以匹配 007, 008,但不能匹配00A,0077,因为\d仅限单个数字字符。 

匹配常用字符

\w可以匹配一个字母、数字或下划线,w的意思是word。

例如:java\w可以匹配,javac,java9,java_,它不能匹配java#,java ,因为\w不能匹配#、空格等字符。

匹配空格字符

\s可以匹配一个空格字符,空格字符不但包括空格,还包括tab字符(在Java中用\t表示)。

例如:a\sc,可以匹配a c, 它不能匹配ac,abc等。

匹配非数字

用\d可以匹配一个数字,而\D则匹配一个非数字。

例如,00\D可以匹配,00A,00#,但不能匹配007008等。

类似的,\W可以匹配\w不能匹配的字符,\S可以匹配\s不能匹配的字符,这正好是相反的。

重复匹配

修饰符*可以匹配任意个字符,包括0个字符。

修饰符+可以匹配至少一个字符。

修饰符?可以匹配0个或一个字符。

如果想精确指定n个字符,用{n}就可以。

如果想指定n~m个字符,用{n,m}就可以。

单个字符的匹配规则如下:

正则表达式规则可以匹配
A指定字符A
\u548c指定Unicode字符
.任意字符ab&0
\d数字0~90~9
\w大小写字母,数字和下划线a~zA~Z0~9_
\s空格、Tab键空格,Tab
\D非数字aA&_,……
\W非\w&@,……
\S非\saA&_,……

 多个字符的匹配规则如下:

正则表达式规则可以匹配
A*任意个数字符空,AAAAAA,……
A+至少1个字符AAAAAA,……
A?0个或1个字符空,A
A{3}指定个数字符AAA
A{2,3}指定范围个数字符AAAAA
A{2,}至少n个字符AAAAAAAAA,……
A{0,3}最多n个字符空,AAAAAA

 复杂规则

匹配开头和结尾

用正则表达式进行多行匹配时,用^表示开头,$表示结尾。

匹配指定范围

使用[...]可以匹配指定范围内的字符,例如[123456789]可以匹配1~9。

如果规定一个7~8位数字的电话号码不能以0开头,规则:[123456789]\d{6,7}

觉得把所有字符列出来太麻烦,[...]还有一种写法,直接写[1-9]就可以。

如果要匹配不限大小写的十六进制数,例如1A2b3c,可以这样写[0-9a-fA-F]

如果要匹配6位十六进制数,前面讲过的{n}仍然可以继续配合使用:[0-9a-fA-F]{6}。

[...]还有一种排除法,能够不包含指定范围的字符。[^1-9],表示不匹配1~9之间的字符。

或规则匹配

| 连接的两个正则规则是或规则,例如,AB|CD表示可以匹配ABCD

使用括号

如果想要匹配字符串learn javalearn Vue learn C#,一个规则是learn\sjava|learn\sVue|learn\sC#,但这样太麻烦了,可以把公共部分提出来,然后用(...)把其表示成learn\s(java|Vue|C#)

复杂匹配规则主要有:

正则表达式规则可以匹配
^开头字符串开头
$结尾字符串结束
[ABC][…]内任意字符A,B,C
[A-F0-9xy]指定范围的字符A,……,F0,……,9xy
[^A-F]指定范围外的任意字符A~F
AB|CD|EFAB或CD或EFABCDEF

分组匹配

(...)还有一个重要作用就是分组匹配。

我们来看一下如何用正则匹配区号-电话号这个规则,利用匹配规则,可以写出:

提示:中间-前的\也是转义字符
\d{3,4}\-\d{6,8}

但如何分别提取出区号和电话号呢,我们可以先把上述正则表达式变为

(\d{3,4})\-(\d{6,8})

之后要按括号提取字符串,必须要用到java.util.regex包,用Pattern对象匹配,匹配后获得一个Matcher对象,如果匹配成功,就可以直接从Matcher.group(index)返回字符串:

要特别注意,Matcher.group(index)方法的参数用1表示第一个子串,2表示第二个子串。如果我们传入0会得到什么呢?答案是010-12345678,即整个正则匹配到的字符串。

使用Matcher时,必须首先调用matches()判断是否匹配成功,匹配成功后,才能调用group()提取子串。

非贪婪匹配

正则表达式默认使用贪婪匹配:任何一个规则,它总是尽可能多地向后匹配。

例如:我们给定一个字符串表示的数字,判断该数字末尾0的个数。

123000, 该正则表达式为:(\d+)(0*)

发现并没有如我们期望的那样分组。

实际上它是完全合理的,因为\d+确实可以匹配后面任意个0。

这是因为正则表达式默认使用贪婪匹配:任何一个规则,它总是尽可能多地向后匹配,因此,\d+总是会把后面的0包含进来。

要让\d+尽量少匹配,让0*尽量多匹配,我们就必须让\d+使用非贪婪匹配。在规则\d+后面加个?即可表示非贪婪匹配。

因此,给定一个匹配规则,加上?后就变成了非贪婪匹配。

注意:?的含义并不相同,\d?表示匹配0个或1个数字,\d??后面的?表示非贪婪匹配。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值