一、匹配验证-验证Email是否正确
public static void main(String[] args) {
// 要验证的字符串
String str = "[email protected]";
// 邮箱验证规则
String regEx = "[a-zA-Z_]{1,}[0-9]{0,}@(([a-zA-z0-9]-*){1,}\\.){1,3}[a-zA-z\\-]{1,}";
// 编译正则表达式
Pattern pattern = Pattern.compile(regEx);
// 忽略大小写的写法
// Pattern pat = Pattern.compile(regEx, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(str);
// 字符串是否与正则表达式相匹配
boolean rs = matcher.matches();
System.out.println(rs);
}
public static void main(String[] args) {
// 要验证的字符串
String str = "baike.xsoftlab.net";
// 正则表达式规则
String regEx = "baike.*";
// 编译正则表达式
Pattern pattern = Pattern.compile(regEx);
// 忽略大小写的写法
// Pattern pat = Pattern.compile(regEx, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(str);
// 查找字符串中是否有匹配正则表达式的字符/字符串
boolean rs = matcher.find();
System.out.println(rs);
}
一个或多个汉字 ^[\u0391-\uFFE5]+$
邮政编码 ^[1-9]\d{5}$(问题:邮政编码可以0开头。修正后为:^[0-9]{6}$或\d{6}等)
QQ号码 ^[1-9]\d{4,10}$
邮箱 ^[a-zA-Z_]{1,}[0-9]{0,}@(([a-zA-z0-9]-*){1,}\.){1,3}[a-zA-z\-]{1,}$(问题:转义字符本身需要转义,即\.应为\\,其它地方同理.)
用户名(字母开头 + 数字/字母/下划线) ^[A-Za-z][A-Za-z1-9_-]+$
手机号码 ^1[3|4|5|8][0-9]\d{8}$(手机号码第二位只能为3458?那也应该修正为:^1[3458]\d{9})
URL ^((http|https)://)?([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$
18位身份证号 ^(\d{6})(18|19|20)?(\d{2})([01]\d)([0123]\d)(\d{3})(\d|X|x)?$
注:原来的有些错误,括号里的为自己修正过的。
特别地:
匹配只包含协议名、主机名的url:
^((http://)|(https://))?((w|W){3}\\.)?[A-Za-z0-9]+\\.((com)|(cn)|(org))$
注意事项:
见第六点。
四、正则表达式语法
元字符描述
\
转义字符
^
匹配输开始位置。如果设置了RegExp对象的Multiline属性,^也匹配“\n”或“\r”之后的位置。
$
匹配结束位置。如果设置了RegExp对象的Multiline属性,$也匹配“\n”或“\r”之前的位置。
*
匹配前面的子表达式任意次。等价于{0,}。
+
比*特殊,匹配前面的子表达式一次或多次。等价于{1,}。
?
匹配前面的子表达式0或1次。如"am?"可以匹配"a","do(es)?"可匹配"does"。等价于{0,1}。
{n}
匹配前面的子表达式确定的n次。如"o{2}"可匹配"hood"中的"oo"。
{n,}
匹配至少重复n次。
{n,m}
匹配至少重复n次,最多重复m次。
?
非重点。当该字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串“oooo”,“o+?”将匹配单个“o”,而“o+”将匹配所有“o”。
.
点 匹配除“\r\n”之外的任何单个字符。要匹配包括“\r\n”在内的任何字符,请使用像“[\s\S]”的模式。
(pattern)
pattern 为子表达式。使用圆括号字符需转义。
(?:pattern)
匹配pattern但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用或字符“(|)”来
组合一个模式的各个部分是很有用。例如“industr(?:y|ies)”就是一个比“industry|industries”更简略的表达
式。当然此处|可替换为其它匹配方式。
(?=pattern)
正向肯定预查,在任何匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需
要获取供以后使用。例如,“Windows(?=95|98|NT|2000)”能匹配“Windows2000”中的“Windows”,但不能匹配
“Windows3.1”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始
下一次匹配的搜索,而不是从包含预查的字符之后开始。
(?!pattern)
正向否定预查,在任何不匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不
需要获取供以后使用。例如“Windows(?!95|98|NT|2000)”能匹配“Windows3.1”中的“Windows”,但不能匹配
“Windows2000”中的“Windows”。
(?<=pattern)
反向肯定预查,与正向肯定预查类似,只是方向相反。例如,“(?<=95|98|NT|2000)Windows”能匹配“2000Windows”
中的“Windows”,但不能匹配“3.1Windows”中的“Windows”。
(?
反向否定预查,与正向否定预查类似,只是方向相反。例如“(?
的“Windows”,但不能匹配“2000Windows”中的“Windows”。
x|y
或。
[xyz]
匹配字符集合。
[^xyz]
不匹配字符集合。
[0-9]
匹配数字。
[a-z]
匹配小写字母。
[A-Z]
匹配大写字母。(以此开始的前三个可自由组合,如[a-zA-Z])
[^a-z]
匹配非该范围内的字母。对大写同理。
\b
匹配单词边界。例如,“er\b”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”。boundary
\B
作用与\b相反。
\d
匹配一个数字字符。等价于[0-9]。digital
\D
匹配一个非数字字符。等价于[^0-9]。
不常用:
\cx
匹配由x指明的控制字符。例如,\cM匹配一个Control-M或回车符。x的值必须为A-Z或a-z之一。否则,将c视为一个原义的“c”字符。
\f
匹配一个换页符。等价于\x0c和\cL。
\n
匹配一个换行符。等价于\x0a和\cJ。
\r
匹配一个回车符。等价于\x0d和\cM。
\s
匹配任何不可见字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]。
\S
匹配任何可见字符。等价于[^ \f\n\r\t\v]。
\t
匹配一个制表符。等价于\x09和\cI。
\v
匹配一个垂直制表符。等价于\x0b和\cK。
\w
匹配包括下划线的任何单词字符。类似但不等价于“[A-Za-z0-9_]”,这里的"单词"字符使用Unicode字符集。
\W
匹配任何非单词字符。等价于“[^A-Za-z0-9_]”。
\xn
匹配n,其中n为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,“\x41”匹配“A”。“\x041”则等价于“\x04&1”。正则表达式中可以使用ASCII编码。
\num
匹配num,其中num是一个正整数。对所获取的匹配的引用。例如,“(.)\1”匹配两个连续的相同字符。
\n
标识一个八进制转义值或一个向后引用。如果\n之前至少n个获取的子表达式,则n为向后引用。否则,如果n为八进制数字(0-7),则n为一个八进制转义值。
\nm
标识一个八进制转义值或一个向后引用。如果\nm之前至少有nm个获得子表达式,则nm为向后引用。如果\nm之前至少有n个获取,则n为一个后跟文字m的向后引用。如果前面的条件都不满足,若n和m均为八进制数字(0-7),则\nm将匹配八进制转义值nm。
\nml
如果n为八进制数字(0-7),且m和l均为八进制数字(0-7),则匹配八进制转义值nml。
\un
匹配n,其中n是一个用四个十六进制数字表示的Unicode字符。例如,\u00A9匹配版权符号(©)。
\< \>
匹配词(word)的开始(\<)和结束(\>)。例如正则表达式\
\( \)
将 \( 和 \) 之间的表达式定义为“组”(group),并且将匹配这个表达式的字符保存到一个临时区域(一个正则表达式中最多可以保存9个),它们可以用 \1 到\9 的符号来引用。
|
将两个匹配条件进行逻辑“或”(Or)运算。例如正则表达式(him|her) 匹配"it belongs to him"和"it belongs to her",但是不能匹配"it belongs to them."。注意:这个元字符不是所有的软件都支持的。
+
匹配1或多个正好在它之前的那个字符。例如正则表达式9+匹配9、99、999等。注意:这个元字符不是所有的软件都支持的。
?
匹配0或1个正好在它之前的那个字符。注意:这个元字符不是所有的软件都支持的。
{i} {i,j}
匹配指定数目的字符,这些字符是在它之前的表达式定义的。例如正则表达式A[0-9]{3} 能够匹配字符"A"后面跟着正好3个数字字符的串,例如A123、A348等,但是不匹配A1234。而正则表达式[0-9]{4,6} 匹配连续的任意4个、5个或者6个数字
五、较常用简单总结
匹配位置:
^(开始位置)、$(结束位置)、\b(单词边界)、\B(非单词边界)
匹配值:
x|y、[a-zA-Z0-9]、[xyz]、[^xyz]、(pattern)、(?:pattern)、(?=pattern)(正向肯定预查)、(?!pattern)(正向否定预查)、(?<=pattern)、(?
正向预查:
预测字符串后面的值等于(=)或不等于(!)pattern匹配的值
反向预查:
预测字符串前面的值等于(<=)或不等于(
匹配值重复次数:
{n}(重复n次)、{n,m}(至少n次,最多m次)、{n,}(最少n次)、?(0或1次)、+(至少1次)、*(任意次)、元字符加?(非贪婪模式,匹配出现1次)
六、部分注意事项
1、[xyz]只匹配单个字符,所以[(ab)]也只能匹配a、b中的一个,而不能将ab作为整体匹配。
2、匹配值重复次数{}里面只能为数字,不能再为匹配表达式。如:
匹配url中域名www.或WWW.不能为:"((w|W){(3|0)}\\.)+",可改为:"((w|W){3}\\.)+",还应注意的是(w|W){3}除了可匹配www与WWW外,还能匹配wWw等,即它将几种|操作的字符视为一种字符,其出现次数为各字符出现次数相加。
3、正则表达式中转义字符本身需要转义,如显示"("应加转义,即为"\(",但正则表达式中转义字符本身也需转义,所以应为"\\("。
4、最好别单独用?(出现一次或0次)。原因:
System.out.println(new String("www").replaceAll("a?", "替换"));
结果为:替换w替换w替换w替换
可见,两个字符之间它出现次数为0,也进行替换。
5、?当该字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的(尽可能少的匹配)。
通过示例理解:
System.out.println(new String("aaabbb").replaceAll(regex,"替换"));
regex取值:结果。分析。
"a*?":
结果:替换a替换a替换a替换b替换b替换b替换。
分析:单独的*匹配连续出现至少0次,所以*?匹配了最少次数(0),即匹配了aaabbb之间与前后的“空隙”,共7处。
"a??":
结果:结果同上。
分析:?匹配连续出现0或1次,所以??匹配了最少次数(0)。
"a+?":
结果:替换替换替换bbb。
分析:+至少匹配1次,所以+?匹配单个a。
"{n}?":
结果:替换abbb。
分析:固定次数的有无?无差异。
"{n,}?":
结果:同上。
分析:取决于n。
"{n,m}?":
结果:同上。
分析:取决于n。
练习:
判断设置的密码(要求至少6位,必须包含数字与字母):
//一个正则表达式无法判断同时包含字母与数字,所以用两个正则表达式
String pass = "asdf12sa";//密码
String regexNum = "[0-9]{1,}";//或"[0-9]+"
String regexLetter ="[a-zA-Z]{1,}";//同上
Pattern pattern1 = Pattern.complie(regexNum);
Pattern pattern1 = Pattern.complie(regexLetter );
Matcher m1 = pattern.matcher(pass);
Matcher m2 = pattern.matcher(pass);
if(m1.find()&&m2.find()){
//密码格式合格
}
七、Pattern 与 Matcher 类