Java正则

我们经常会用到判断一个字符串是否符合某一规则,像是否是一个有效手机号,是否是一个有效身份证号等等。

如果使用程序逻辑运算符判断,那可能是一个繁杂的任务,但是有了正则表达式,我们可以通过定一个一个简短的规则起到强大的约束作用。

精准匹配

精准匹配使用String.equals()就能实现,这并不是他真正的用武之地。

匹配规则

正则表达式的验证规则是从左到右按规则匹配。

\d是一个完整匹配单元,java中如果想要完整表达\d,字符串中应当输入\\d

单个匹配规则

字符

.匹配一个任意字符

1
2
3
4
5
System.out.println("&".matches("."));//true
System.out.println(".".matches("."));//true

System.out.println("".matches("."));//false
System.out.println("aa".matches("."));//false

数字

\d匹配一个数字字符

\D匹配范围相当于!d

\d是一个完整匹配单元,java中如果想要完整表达\d,字符串中应当输入\\d

1
2
3
4
System.out.println("a1".matches("a\\d"));//true

System.out.println("aa".matches("a\\d"));//false
System.out.println("a11".matches("a\\d"));//fasle

常用字符(字母、数字、下划线)

\w匹配一个字母、数字、下划线字符

\W匹配范围相当于!w

1
2
3
4
5
6
System.out.println("A".matches("\\w"));//true
System.out.println("1".matches("\\w"));//true
System.out.println("_".matches("\\w"));//true

System.out.println("&".matches("\\w"));//false
System.out.println("\u548c".matches("\\w"));//false

空字符

\s匹配一个空格字符,不是空格,还包括tab

\S匹配范围相当于!s

1
2
3
4
5
6
7
8
System.out.println(" ".matches("\\s"));//true
System.out.println("\t".matches("\\s"));//true
System.out.println("\n".matches("\\s"));//ture
System.out.println("\f".matches("\\s"));//true
System.out.println("\t".matches("\\s"));//true

System.out.println("\b".matches("\\s"));//false
System.out.println("\'".matches("\\s"));//false

多个匹配规则

这几个匹配符不可以单独使用

1
2
System.out.println("a".matches("*"));
//编辑器报错 "*" Dangling metacharacter

*匹配0~∞个任意字符

1
2
3
System.out.println("".matches("\\d*"));//true
System.out.println("1".matches("\\d*"));//true
System.out.println("11".matches("\\d*"));//true

+匹配1~∞个任意字符

1
2
3
4
System.out.println("1".matches("\\d*"));//true
System.out.println("11".matches("\\d*"));//true

System.out.println("".matches("\\d*"));//false

?匹配0~1个任意字符

1
2
3
4
System.out.println("".matches("\\d*"));//true
System.out.println("1".matches("\\d*"));//true

System.out.println("11".matches("\\d*"));//false

{m}匹配M个字符

1
2
3
4
System.out.println("1".matches("\\d{1}"));//true

System.out.println("".matches("\\d{1}"));//false
System.out.println("11".matches("\\d{1}"));//false

{m,n}匹配M~N个字符

1
2
3
4
5
System.out.println("1".matches("\\d{1,3}"));//true
System.out.println("111".matches("\\d{1,3}"));//true

System.out.println("".matches("\\d{1,3}"));//false
System.out.println("1111".matches("\\d{1,3}"));//false

{m,}匹配m~∞个字符

1
2
3
4
System.out.println("1".matches("\\d{1,}"));//true
System.out.println("1111111111111".matches("\\d{1,}"));//true

System.out.println("".matches("\\d{1,}"));//false

复杂匹配规则

匹配开头和结尾

多行匹配时^表示开头,$表示结尾。

匹配指定范围

[...]匹配范围,如:

[0123456789],可以匹配0~9,也可以写成[0-9]

类似的还有:

[0-9a-fA-F]表示不限制大小写的十六进制

[a-zA-Z]表示不限制大小写的字母

拓展:

\可以通过[A-z],推断应该应该是ASCII表中的位序来判断的。以下结果全为true

1
2
3
4
5
6
7
System.out.println("[".matches("[A-z]"));//91
System.out.println("\\".matches("[A-z]"));//92
System.out.println("]".matches("[A-z]"));//93
System.out.println("^".matches("[A-z]"));//94
System.out.println("_".matches("[A-z]"));//95
System.out.println("`".matches("[A-z]"));//96
System.out.println("_".matches("[^-`]"));

如果表达式写成z-A,编译器报错 Illegal character range (to < from),更是印证了我们猜想。

反向匹配范围

[^...]表示![...]

1
System.out.println("@".matches("[^A-z]"));

|来连接两个正则表达式

bcBC可以用bc|BC来匹配。

括号

类似于提取公因子

3×2+3×1=>3×(2+1)

AbcABC可以用A(bc|BC)来匹配。