Java —— 正则表达式 Regex

来源:互联网 发布:pc安装mac os x 10.11 编辑:程序博客网 时间:2024/06/03 14:38
转载自:http://baike.xsoftlab.net/view/207.html#4


Java正则表达式的语法与示例

概要:
Java正则表达式的语法与示例

一、匹配验证-验证Email是否正确

public static void main(String[] args) {    // 要验证的字符串    String str = "service@xsoftlab.net";    // 邮箱验证规则    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”。

(?<!pattern)

反向否定预查,与正向否定预查类似,只是方向相反。例如“(?<!95|98|NT|2000)Windows”能匹配“3.1Windows”中

的“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匹配版权符号(&copy;)。
\< \>

匹配词(word)的开始(\<)和结束(\>)。例如正则表达式\<the\>能够匹配字符串"for the wise"中的"the",但是不能匹配字符串"otherwise"中的"the"。注意:这个元字符不是所有的软件都支持的。
\( \)

将 \( 和 \) 之间的表达式定义为“组”(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)

正向预查:

预测字符串后面的值等于(=)或不等于(!)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 类








原创粉丝点击