单个字符匹配
1. 精确匹配
-
• 对于正则表达式
abc
,只能精确匹配字符串"abc"
,而不能匹配"ab"
,"Abc"
,"abcd"
等其他任何字符串。 -
• 如果正则表达式有特殊字符,需要用
\
转义。比如,正则表达式a\&b
,其中\&
是用来匹配特殊字符&
的,它能精确匹配字符串"a&b"
,但是不能匹配"ac"
、"a-c"
、"a&&c"
等字符串。
注意:正则表达式在Java代码中也是一个字符串,所以,对于正则表达式
a\&b
,对应的Java字符串是"a\\&b"
,因为\
也是Java字符串的转义字符,两个\\
实际上表示的是一个\
:
-
• 如果想匹配非ASCII字符,例如中文,就用十六进制表示,例如:
a\u548cb
匹配字符串"a和b"
,中文字符和
的Unicode编码是548c
。
2. 匹配任意字符
.
精确匹配一般用的比较少,我们直接通过String
类的equals()
方法就可以实现。大多数情况下,我们想要模糊匹配。我们可以用.
匹配一个任意字符。
例如,正则表达式a.b
中间的.
可以匹配一个任意字符,下面的字符串都可以匹配到:
"abb"
"a&b"
"acb"
注意 但它不能匹配
"ab"
、"a&&b"
,因为.
匹配一个字符且仅限一个字符。
3. 匹配数字
\d
如果我们只想匹配0~9
这样的数字,可以用\d`匹配。
例如,正则表达式00\d
,可以匹配:
001
002
003
注意:它不能匹配
"0011"
、"0022"
,因为\d
仅限单个数字字符。
4. 匹配字母、数字或下划线
\w
w的意思是word,可以匹配一个字母、数字或下划线。
例如,hello\w
可以匹配:
hello1
hellow
hello_
它不能匹配
hello#
、hello@
、helloworld
等,因为\w
只能匹配一个字符,且仅支持字母、数字或下划线
5. 匹配空格字符和制表符
\s
例如,a\sb
可以匹配:
a b
a b
它不能匹配
ab
、acb
,因为\s
仅限单个空格或者\t
字符。
6. 匹配非数字
\D
用\d
可以匹配一个数字,而\D
则匹配一个非数字。
例如,00\D
可以匹配:
00A
00#
00@
同样的,\W
可以匹配\w
不能匹配的字符,\S
可以匹配\s
不能匹配的字符。
小结:
正则表达式 | 规则说明 | 示例 |
a | 精确匹配 | a |
\u548c | 指定一个Unicode字符 | 和 |
. | 任意一个字符 | a,b,#,¥ |
\d | 任意一个数字(0~9) | 0 ~ 9 |
\w | 任意一个大小写字母,数字和下划线 | az,AZ,0~9,_ |
\s | 空格、Tab键 | 空格,Tab |
\D | 非数字 | a,A,&,_ |
\W | 非\w | |
\S | 非\s |
多个字符匹配
上面介绍的只能每次匹配一个字符,如果要匹配多个字符,怎么办呢?我们可以使用修饰符来实现。
1. 匹配0个或者任意多个字符
*
例如,a\d*
可以匹配:
a
a0
a111
2. 匹配至少一个字符
+
例如,a\d+
可以匹配:
a0
a10
注意:但它无法匹配
"a"
,因为修饰符+
要求至少一个字符。
3. 匹配0个或一个字符
?
例如,a\d?
可以匹配:
a
a0
注意:但它无法匹配
"a10"
,因为修饰符?
超过1个字符就不能匹配了。
4. 匹配n个字符
{n}
例如,a\d{3}
,可以匹配:
a110
5. 匹配n~m个字符
{n,m}
例如,a\d{1,3}
,可以匹配:
a0
a10
a110
6. 匹配至少n个字符
{n,}
例如,a\d{3,}
,可以匹配:
a110
a110111010101010
7. 匹配最多n个字符
{0,n}
例如,a\d{0,3}
,可以匹配:
a0
a01
a001
小结:
正则表达式 | 规则说明 | 示例 |
* | 任意个数字符 | |
+ | 至少1个字符 | |
? | 0个或1个字符 | |
{n} | 指定n个字符 | |
{n,m} | 指定n~m范围字符 | |
{n,} | 至少n个字符 | |
{0,n} | 最多n个字符 |
复杂规则匹配
1. 匹配开头和结尾
匹配开头:^
匹配结尾:$
我们用^
表示开头,$
表示结尾。例如,^A\d{3}$
,可以匹配"A001"
、"A380"
。
2. 匹配指定范围
[...]
我们可以使用[...]
可以匹配范围内的字符,例如:
-
•
[123456789]
可以匹配1
~`9,还有一种写法,直接写
[1-9]`就可以。 -
• 匹配大小写不限的十六进制数,比如
1A2b3c
,我们可以这样写:[0-9a-fA-F]
-
•
[...]
还有一种排除法,即不包含指定范围的字符。假设我们要匹配任意字符,但不包括数字,可以写[^1-9]{1}
3. 或规则匹配
|
用|
连接的两个正则规则是或规则,例如,A|C
表示可以匹配A
或C
。
4. 使用括号
(...)
-
• 提取公共部分我们想要匹配字符串
hello java
、hello php
和hello go
一般是这样写的:hello\sjava|hello\sphp|hello\sgo
,可以把公共部分提出来,然后用(...)
把子规则括起来表示成hello\\s(java|php|go)
。 -
•
(...)
的另一种用法,可以实现分组匹配。有这样一个正则表达式:\d{3,4}\-\d{6,8}
,匹配的是区号-电话号
。匹配成功后,我们想提取区号和电话号码,分别存入数据库。我们可以这样做:先用(...)
先把要提取的规则分组,把上述正则表达式变为(\d{3,4})\-(\d{6,8})
。然后使用java中的Matcher.group
返回子串,如下:
import java.util.regex.*;
public class Test {
public static void main(String[] args) {
Pattern p = Pattern.compile("(\\d{3,4})\\-(\\d{7,8})");
Matcher m = p.matcher("010-12345678");
if (m.matches()) {
String g1 = m.group(1);
String g2 = m.group(2);
System.out.println(g1);
System.out.println(g2);
} else {
System.out.println("匹配失败!");
}
}
}
这样,我们就能将区号和电话号码分别提取出来了。