正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。在众多语言中都可以支持正则表达式,如Perl、PHP、Java、Python、Ruby等。本文中以java为例子。
目录
一、正则表达式语法
-
除了下面提到的特殊字符外,其他所有字符匹配它本身。 如a就匹配a
-
.匹配任意字符
-
? 表示出现一次或不出现。等价于{0,1}
-
+ 表示出现一次或多次,匹配尽可能多(贪婪模式)等价于{1,}
-
* 表示出现任意次(贪婪模式)等价于{0,}
-
+?表示一次或多次,匹配尽可能少(非贪婪模式)
例:<str1><str2> <.+>将匹配<str1><str2> <.+?>将匹配<str1>
-
*?和?? 类比上一条
-
[] 表示匹配中括号中其中任一个字符,如[xyz]可以匹配x或y或z
ps:符号- 在[]中并不匹配实际字符,而表示范围,如[a-z]可表示从a-z的字符中任意一个,如b,e等。
-
{} 放在某字符串后表示重复出现n次 如a{2}匹配aa
此外, a{1,4}匹配1到4次,如aaa
{1,}表示匹配一次以上,如aa -
|表示“或”的关系,运算优先级低于字符,如abc|de匹配abc和de
-
() 标记一个子表达式,并改变一些符号的作用范围,并在匹配时进行提取。可和|,+等联用
例:ab(c|d)e匹配abce或abde (ab){2}匹配abab
-
(?: ) 只改变一些符号的作用范围,但并不提取。二者区别会在下面谈到。
-
^ 在[]外表示字符串的开始位置,在[]内紧跟[后表示取后面字符的补集
例:b能匹配abc的b,而^b则不能,但^ab能匹配其中的ab [^a-z]能匹配除小写字母外所有的字符
-
$ 表示字符串结束的位置 ,类比^
-
\ 可以放在以上的特殊字符前,取消其特殊含义,如\+匹配加号+。而\\表示普通含义的\。需要注意的是,在以java为代表的很多语言中,本身就需要用两个斜杠\\来表示一个斜杠\。用正则表达式匹配普通斜杠时,需要输入四个斜杠\\\\(而我在用markdown编辑这篇博客时甚至用了八个斜杠)
tips: eclipse 中向双引号""中复制字符串时,会自动加上斜杠取消那些字符的特殊含义,可以加以利用防止被绕晕。但同时也避免忘了这一点而导致多此一举。
-
\和一些字母连用有含义:如:
16.1. \d 匹配一个数字字符,等价于[0-9]
16.2. \w 匹配英文字母、数字或下划线,等价于[0-9a-zA-Z_]
16.3 \D ,\W表示\d, \w的补集. 如\D等价于[^0-9]
类似的特殊字符还有很多,在此不一一列举。
二、正则表达式在Java中的运用
1.String的split(String pattern)方法
该方法传入的是一个正则表达式,格外注意不要将参数当成普通字符串传入导致意料之外的转义。
例:以"."作为分隔符分割字符串s,要使用s.split("//.")
2. java.util.regex包
对一个正则表达式pattern,首先需要进行编译:
Pattern r = Pattern.compile(pattern);
然后再和传入待匹配的字符串str
Matcher m = r.matcher(str);
之后,即可调用m的各类方法实现需求
提取匹配的字符串m.find()
若匹配成功返回true,失败返回false。
注:这并非一个observer,而是会进行匹配,改变m的内部字段,调用该方法成功后才能进行提取。
若成功匹配,则调用函数m.group(int i)返回第i个用正则表达式中用()提取的子表达式,i为0时返回匹配到的整个字符串。
//pattern="([a-z]+)//d+([a-z]+)",str="-abc123def#" 已通过上面的方法得到m
if(m.find()){
String s0 = m.group(0);//"abc123def"
String s1 = m.group(1);//"abc"
String s2 = m.group(2);//"def"
}
若pattern为"(?:[a-z]+)//d+([a-z]+)“,则m.group(1)会返回"def”,而m.group(2)会报错
替换字符串 replaceFirst和replaceAll
顾名思义 前者只替换首次匹配到的字符串,而后者会替换到所有匹配到的字符串
例:pattern=“[a-z]+”,str=“-abc123def#”,rep=“xyz”,若已通过上面的方法得到m。
则m.replaceFirst(rep);
会使str变成"-xyz123def#"
而m.replaceAll(rep);
会使str变成"-xyz123xyz#"
参考:菜鸟教程《正则表达式-语法》 《Java正则表达式》