一、简介
正则表达式简单来讲是一种文本模式,用来匹配某个规则的字符串,虽然规则比较繁琐,但是功能却很强大,应用在某些地方能够大大提高效率。正则表达式的应用也十分广泛,比如网站注册时Email格式校验、文件搜索的表达式、Nginx的路由规则等等。各种语言对正则表达式都有很好的支持,所以学习正则表达式绝对是超值的买卖,只不过需要记的东西比较多,但是常用的正则表达式还是比较容易记的。
二、正则表达式语法
1、界定符
界定符就是正则表达式开始、结束的标志。这个可以告诉解析器正则表达式从哪里开始,从哪里结束;不同语言对界定符规定不一样,我们可以认为界定符不属于正则表达式的内容。
2、元字符
元字符属于字符,也叫原子,是不可分割的一个单位。字符分为可打印字符和不可打印字符,可打印字符比如常见的字母、数字等,不可见字符比如换行符、制表符。由于篇幅限制本文选取常用的元字符,按照其分类来讲解。
3、筛选方式
“|”匹配两边的分支,比如“abc | d”,表示匹配abc或者d;
“[]”匹配中括号中的任意一个元字符,比如“[ab]”表示匹配a或者b;
“[^]”匹配中括号里面原子之外的任意字符,比如“[^ab]”,表示匹配a、b以外的任何字符;
这里面有几个注意的地方,“[]”里面只能填元字符,但是“|”两边可以写任何东西; “[^]”中“^”必须在”[”后面,否则就不是取反了,比如“[3^4-7]”就是匹配3、^、4到7的数字。如果要匹配一些特殊字符比如“*”,“\”,“.”就需要使用“\”转义。
4、元字符集合
“.”匹配换行符之外的任何字符;
“\d”匹配任意一个十进制数字,即[0-9];
“\D”匹配任意一个非十进制数字,即[^0-9];
“\s”匹配一个不可见元字符,即[\f\n\r\t\v],其中\f表示换页符,\n表示换行符,\r回车符、\t表示制表符,\v表示垂直制表符;
“\S”匹配一个可见原子,即[^\f\n\r\t\v];
“\w”匹配任意一个数字、字母或下划线,即[0-9a-zA-Z];
“\W”匹配任意一个非数字、字母或下划线,即[^0-9a-zA-Z];在中括号里面,0-9是一个元字符,a-z是一个元字符,A-Z是一个元字符;
5、量词
“”表示前面的原子恰好出现n次;
“”表示前面的原子最少出现n次;
“”表示前面的原子最少出现n次,最多出现m次;
“*”表示前面的原子出现0次、1次或多次,即“”;
“+”表示前面的原子出现1次或多次,即“”
“?”表示前面的原子出现0次或1次,即“”
量词不仅支持元字符,还支持元字符的集合,比如“[a-zA-Z]”匹配两个连续出现的字母。
6、边界控制
“^”匹配字符串开始的位置,比如“^abc”表示匹配abc开头的字符串;
“$”匹配字符串结束的位置;“78$”78结尾的字符串,;
“()”将括号内的字符当成一个元字符,比如“(J|j)ay”表示匹配Jay或jay;
7、修正模式
当我们使用正则表达式的时候,可能会出现多个匹配结果,比如“jay.+6”的匹配结果有多个,jaychou6能匹配的到,jaychou666也能匹配的到,但是正则表达式默认是贪婪模式的,贪婪模式就是尽量匹配多的字符串,另一种模式是懒惰模式,就是尽可能少的匹配,当我们要使用懒惰模式时,需要指定它为懒惰模式。另外还有其他比如忽略字母大小写、忽略空白等。
三、两个小例子
1、匹配邮箱:^\w+(.\w+)@\w+(.\w+)+$
^\w+表示字母、数字、下划线开头出现1次或多次,然后看第一个括号,里面的“.”本来表示匹配换行符之外的任何字符,但是这里用“\”转义了,在这里就直接匹配“.”,接着“\w+”和前面一样,括号不是把里面的都当成一个元字符吗,后面的“”表示括号这整个元字符可以出现0次1次或多次,然后@表示匹配@符号,后面的“\w+”、“(.\w+)+”和前面一样,最后一个$表示必须以“.”加字母数字下划线结尾。
2、匹配两位小数:\d+.\d$
按照上面的思路,“\d+”表示数字出现一次或多次,后面接着匹配一个“.”,然后数字又出现两次,但是必须是以这两个数字结尾。
四、Java中的正则表达式
Pattern类
这个类是正则表达式的编译表现形式。指定的正则表达式必须被编译成此类的实例,然后可将得到的模式用于创建Matcher对象,依照正则表达式,该对象可以与任意字符序列匹配。
典型的调用顺序是
Pattern pattern = Pattern.compile("a*e");
Matcher matcher = pattern.matcher("aaaae");
boolean b = m.matches();
当仅使用一次正则表达式时,可以方便地通过该类的matches()方法,代码为boolean b = Pattern.matches(“a*b”, “aaaaab”);等效于上面三个语句,因为它不允许重用已编译的模式,所以对于重复匹配它效率不高。另外一点就是Pattern类的实例是不可变的,可供多个并发线程安全使用。
Matcher类
通过解释模式(Pattern),对字符串执行匹配操作的引擎,通过调用模式(Pattern)的matcher方法创建Matcher类的实例,也就是一个匹配器,创建匹配器后可以使用它执行不同的匹配操作,返回成功或者失败的布尔值,而且还可以通过查询匹配器状态获取关于成功匹配的更多信息。
PatternSyntaxException类
表示正则表达式模式中的语法错误。
MatchResult接口
这是一个接口,匹配操作的结果,Matcher类实现了该接口。通过MatchResult可以查看匹配边界、组和组边界,但是不能修改。
在String类里面,split()方法可以传正则表达式,来分割字符串,replace()、replaceAll()方法可以传正则表达式来替换字符串,如果字符串中有一些字符,比如汉字、日文等,在正则匹配的时候回因为编码问题而出现错误,解决方案就是将汉字、日文转为Unicode编码再进行匹配。
领取专属 10元无门槛券
私享最新 技术干货