目录
1.什么是正则表达式
正则表达式是一个字符串,用来描述匹配一个字符串集合的模式。对于字符串处理来说,正则表达式是一个强大的工具。可以使用正则表达式来匹配、替换和拆分字符串。
2.正则表达式用法
(1)匹配字符串
String类中的matches方法,很类似equals方法,例如,以下两个语句结构都为true
"Java".matches("Java");
"Java".equals("Java")
但是matches不仅可以匹配一个固定的字符串,还可以匹配符合一个模式的字符串集。
"Java is fun".matches("Java.*")
"Java is cool".matches("Java.*")
"Java is powerful".matches("Java.*")
以上结果都为true,前面语句中的"Java.*"是一个正则表达式。它描述了一个字符串模式,以Java开始,后面跟0个或者多个字符串。子字符串 .* 匹配0或者多个任意字符。
(2)正则表达式语法
正则表达式由字面值字符和特殊符号表示,下表列出了正则表达式常用的用法。
注意:1.反斜杠是一个特殊的字符,在字符串中开始转义序列.因此Java需要使用\\来表示\
2.空白字符是' ','\t','\n','\r',或者'\f'.因此,\s和[\t\n\r\f]等同,\s和[^ \t\n\r\f]等同.
3.单词字符是任何的字母,数字或者下划线字符.因此\w等同于[a-z[A-Z][0-9]_]或者简化为[a-Za-z0-9]. \w等同于[^a-Za-z0-9].
4.表中后面六个条目 * 、+、?、{n}、{n, }以及{n,m}称为量词符,用于确定量词符前面的模式会重复多少次。
例如,A*匹配0或多个A,A+匹配1或者多个A,A?匹配0或者1个A。A{3}精准匹配“AAA”, A{3, }匹配至少3个A,A{3,6}匹配3到6个A。*等同于{0,},
+等同于{1,},?等同于{0.1}。
5.可以使用括号来将模式进行分组.例如(ab){3}匹配ababab , 但是ab{3}匹配abbb.
警告:不要在重复量词符中使用空白.例如, A{3,6}不能写成逗号后面有一个空白符的A{3, 6}
下面是一些构建正则表达式的示例.
示例1
社会安全号的模式是xxx-xx-xxx,其中x是一位数字. 社会安全号的正则表达式可以描述为
[\\d]{3}-[\\d]{2}-[\\d]{4}
例如
"111-22-3333".matches("[\\d]{3}-[\\d]{2}-[\\d]{4}") return true.
"11-22-3333".matches("[\\d]{3}-[\\d]{2}-[\\d]{4}") return false.
示例2
偶数以数字0,2,4,6,8结尾. 偶数的模式可以描述为
[\\d]*[02468]
例如
"123".matches("[\\d]*[02468]") return false.
"122".matches("[\\d]*[02468]") return true.
注意:这里的[\\d]指的是“123”里面靠近matches最近的一个数字“3”,和“122”的“2”,而不是“123”和“122“这两个数。
示例3
电话号码的模式是(xxx)xxx-xxxx, 这里x是一位数字, 并且第一位数字不能是0. 电话号码的正则表达式可以描述为:
\\([1-9][\\d]{2}\\)[\\d]{3}-[\\d]{4}
注意:括号符” ( “和” )“在正则表达式中是特殊字符,用于对模式分组。为了在正则表达式中表示字面值”( “和” )“时,必须用” \\( “和” \\) “。
例如
"(912) 921-2728".matches("\\([1-9][\\d]{2}\\)[\\d]{3}-[\\d]{4}")
return true.
"921-2728".matches("\\([1-9][\\d]{2}\\)[\\d]{3}-[\\d]{4}")
return false.
示例 4
假定姓最多由25个字母组成,并且第一个字母为大写形式。则姓的模式可以描述为
[A-Z][a-zA-Z]{1,24}
注意: 不能随便放空白符到正则表达式中。如[A-Z][a-zA-Z]{1, 24}将报错
例如
"Smith".matches("[A-Z][a-zA-Z]{1,24}") return true.
"Jones123".matches("[A-Z][a-zA-Z]{1,24}") return false.
示例 5
Java标识符
* 标识符必须以字母、下划线(_),或者美元符号($)开始。不能以数字开头。
* 标识符是一个由字母、数字、下划线(_)和美元符号组成的字符序列。
标识符的模式可描述为
[a-zA-Z_$][\\w$]*
示例 6
什么字符串匹配正则表达式“Welcome to (Java|HTML)"?答案是Welcome to Java或者Welcome to HTML。
示例 7
什么字符串匹配正则表达式" .*"?答案是任何字符串。
(3)替换和拆分字符串
如果字符串匹配正则表达式,String类的matches方法返回 true。String类也包含repalceAll、replaceFirst和split方法,用于替换和拆分字符串,如下图所示。
replaceALL方法替换所有匹配的子字符串,replaceFirst方法替换第一个匹配的字符串。例如
代码
System.out.println("Java Java Java".replaceAll("v\\w","wi"));
显示
Jawi Jawi Jawi
代码
System.out.println("Java Java Java".replaceFirst("v\\w","wi"));
显示
Jawi Java Java
有两个重载的 split 方法。split(regex)方法使用匹配的分隔符将一个字符串拆分为子字符串。
例如,以下语句
String[] tokens = "Java1HTML2Per1".split("\\d");
将字符串"JavaHTML2Per1"拆分为Java、HTML 以及Per1并且保存在tokens[0],tokens[1]以及tokens[2]中。
在split(regex,limit)方法中,limit参数确定模式匹配多少次。如果1imit <= 0,split(regex,1imit)等同于split(regex)。如果limit > 0,模式最多匹配1imit -1次。
下面是一些示例:
"Java1HTML2Perl".split("\\d",0);拆分为Java,HTML,Perl
"Java1HTML2Perl".split("\\d",1);拆分为Java1HTML2Perl
"Java1HTML2Perl".split("\\d",2);拆分为Java,HTML2Perl
"Java1HTML2Perl".split("\\d",3);拆分为Java,HTML,Perl
"Java1HTML2Perl".split("\\d",4);拆分为Java,HTML,Perl
"Java1HTML2Perl".split("\\d",5);拆分为Java,HTML,Perl
注意:默认情况下,所有的量词符都是“贪婪”的。这意味着它们会尽可能匹配最多次。比如,下面语句显示JRvaa。因为第一个匹配成功的是aaa。
System.out.println("Jaaavaa".replaceFirst("a+","R"));
可以通过在后面添加问号(?)来改变量词符的默认行为。量词符变为“不情愿”或者“惰性”的,这意味着它将匹配尽可能少的次数。例如,下面的语句显示]Raavaa,因为第一个匹配成功的是a。
System.out.println("Jaaavaa".replaceFirst("a+?”,"R"));