正则表达式:在代码中常写为regex、regexp、或RE,从JDK1.4开始引入。
目的:更加灵活的实现字符串的匹配、拆分、替换等操作。
问题引出
我常说,我们以开发者角度看代码,或知识点,最重要一条就是:常问自己,这个东西有什么用?
正则表达式实际上是一组规范。
给一道例题:要求判断某一个字符串是否由数字组成。
我们需要注意两点:1.为了能够判断每一位字符数据,需要将字符串转换为字符数组,这样便于循环判断。
2.判断字符数组中的每一个字符是否在“0-9”之间
重点来了,“0-9”
上面一段代码大家都不陌生,但是:就这样一个简单的操作,却要开发者编写超过10行的代码,是不是有点麻烦了?
简化:正则
好不好玩?
好,我们先说说有什么用:
1.在注册登录页面,用户是不是需要填一个“密码”框,这个里面一般都需要纯数字,而且,就算可以有字符,正则还是可以应付这些(我们下面会提到)
2.还是注册页面,判断用户是不是按要求输入了身份证号,怎么办?——用正则呀
3.在一份文件中,需要统计比如说一共有多少个单词,怎么办?——用正则
。
。
。
匹配字符串
让我们从String类中的matches方法开始。乍一看,这个方法很类似于equals方法。例如:
这两句的结果就都为true;
But,matches方法强大在于,它不仅可以匹配固定字符串,还可以匹配一个模式的字符串集,例如:
语句中的“java.”就是正则表达式。它描述了一个字符串模式,以java开始,后面跟0个或多个字符串。这里,子字符串“.”匹配任何0个或多个字符(下面会提到)
正则表达式语法
由字面值字符和特殊符号组成。下面列出一些常用语法:
(注意:反斜杠是一个特殊的字符,在字符串中开始转义序列。因此,java中需要使用\d来表示\d)
(注意:回顾下,空白字符是:’ ‘、’\t’、’\n’、’\r’,或者:’\f’。因此,\s和[\t\n\r\f]等同,\S和[^\t\n\r\f]等同——别着急,往下看)
. ->任一单个子符(java匹配j…a)
(ab|cd) ->ab或cd(tent匹配t(en|rm)t)
[abc] ->a、b或c
[^ abc] ->除a、b、c以外的任意字符(java匹配ja[^ars]a)
[a-z] ->小写字母a-z
[a-e[m-p]] ->a-e或m-p(java匹配[a-g[i-m]]av[a-d])
[a-e&&[c-p]] ->a-e与c-p的交集(java匹配[a-p&&[i-m]]av[a-d])
\d ->单个数字,等同于:[0-9]
\D ->一位非数字
\w ->单词字符
\W ->非单词字符
p* ->模式p的0次或多次出现
p+ ->模式p的1次或多次出现
p? ->模式p的0次或1次出现
p{n} ->模式p的正好n次出现
p{n,} ->模式p的至少n次出现
p{n,m} ->模式p出现次数位于n和m之间(不包含)
(注意:单词字符是任何的字母,数字或下划线字符。因此\w等同于[a-z[A-Z][0-9]]或者简化为[a-Za-z0-9])
(注意:不要在重复量词符中使用空白。例如:A{3,6}不能写成逗号后面有一个空白符的A{3, 6})
(注意:可以使用括号来将模式进行分组。例如:(ab){3}匹配ababab,但是ab{3}匹配abbb)
示例
让我们用一些示例来演示如何构建正则表达式。
示例一:
社会安全号的模式是:xxx-xx-xxxx,其中x是一位数字。
先想。。。
示例二:
偶数数字以0/2、4、6、8结尾。偶数的模式可以描述为:
先想。。。
硬核,替换和分割字符串
我们知道,在java的String类中,包含有replaceAll、replaceFirst、和split方法,用于分割和替换字符串:
用replaceAll替换所有匹配的字符串,而用replaceFirst方法替换第一个匹配的子字符串。
那放在正则里怎么用呢?
例如,下面代码:
结果:jawi jawi jawi
java中的分割方法A:split,这里不再详说。。。
还要注意一点:默认的,所有的量词都是“贪婪的”。这意味着它们会尽量匹配可能的最多次。比如,下面语句显示jrvaa。因为第一个匹配成功的是aaa。
我们可以通过**在后面添加问号符号 **来改变量词的默认行为。量词符变为“不情愿”的,这意味着它将匹配尽可能 少的次数。例如,下面的语句显示jraavaa,因为第一个匹配成功的是a。
大招 - 实践操作