您的位置:首页 > 编程语言 > Java开发

[学习笔记]Java正则表达式

2016-04-16 13:49 495 查看

1.概述

正则表达式是用于描述字符串复杂规则的工具,换句话说,正则表达式就是记录文本规则的代码。

2.优势与劣势

优势:用了一些符号来代表这些代码,书写起来更为简单。

劣势:因为都是一些符号组成的表达式,所以阅读起来可读性不高,而且先要把符号学完。

3.格式

3.1元字符

.匹配除换行符以外的任意字符
\w匹配字母或数字或下划线或汉字
\s匹配任意的空白符
\d匹配数字
\b匹配单词的开始或结束
^匹配字符串的开始
$匹配字符串的结束

示例

\b\w\w\b:匹配由2个字母构成的单词。(Java字符串中为"\\b\\w\\w\\b")

3.2限定符

*重复零次或更多次
+重复一次或更多次
?重复零次或一次
{n}重复n次
{n,}重复n次或更多次
{n,m}重复n到m次

示例

\ba\w*\b:匹配以字母a开头的单词。(Java字符串中为"\\ba\\w*\\b")
\d+:匹配1个或更多连续的数字。(Java字符串中为"\\d+")
\b\w{6}\b:匹配刚好6个字符的单词。(Java字符串中为"\\b\\w{6}\\b")

3.3字符与字符转义

单个字符的判断可以使用集合概念,只需使用"[]"即可,例如:"[aeiou]"匹配任何一个英文元音字母。
在Java字符串中,由于字符"\"本身具有转义性,所以凡是带有"\"的正则表达式,均需要使用"\\"来替代"\"。例如上述例子"\d+"在Java字符串中应写成"\\d+"。
如果需要匹配正则表达式中有特殊意义的字符本身,需要使用"\"进行转义。例如可以使用正则表达式"\\w*\.\\w*"来匹配"abc.com"。

示例

\(?0\d{2,3}[)-]?\d{7,8}:匹配几种格式的电话号码,类似(010)88886666,或0554-22334455,或05541234567等。

3.4分支条件(逻辑或)

如果多种情况需要匹配,可以使用"|"将多种正则表达式连接在一起成为一个,任何满足其中一个正则表达式即可匹配。

示例

0\d{2}-\d{8}|0\d{3}-\d{7}:匹配两种以连字号分隔的电话号码:一种是三位区号,8位本地号(如010-12345678),一种是4位区号,7位本地号(0376-2233445)。

3.5分组

如果需要对多个字符进行重复或者在Java字符串中进行替换处理,可以使用分组,符号为"()"。
Java字符串处理中,使用"\数字"来代替前面的第几个分组,例如"(.)\\1+"匹配出现连续相同字符。

示例

(\d{1,3}\.){3}\d{1,3}:简单的IP地址匹配表达式,但是类似"111.222.666.999"的IP地址也视为匹配。
((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?):IP地址匹配表达式,由于正则表达式不支持数学运算和比较,所以只能使用繁杂的分组和分支来实现。

3.6反义

\W匹配任意不是字母,数字,下划线,汉字的字符
\S匹配任意不是空白符的字符
\D匹配任意非数字的字符
\B匹配不是单词开头或结束的位置
[^x]匹配除了x以外的任意字符
[^aeiou]匹配除了aeiou这几个字母以外的任意字符

示例

\S+:匹配不包含空白符的字符串。


字符串(String类)

1.匹配

方法

booleanmatches(Stringregex)

示例

Stringnum="13988887777\nhaha";
StringnumRegex="[1][3578]\\d{9}";//匹配手机号码
booleanb=num.matches(numRegex);


2.分割

方法

String[]split(Stringregex)
String[]split(Stringregex,intlimit)

示例

publicstaticvoidsplit(){
Stringstr1="itheima.java.jacob.meteor";
//按“.”分割字符串
Stringregex1="\\.";
Stringstr2="itheimajavajacob\tmeteor";
//按空白字符分割字符串
Stringregex2="\\s+";
Stringstr3="itheimaeeejava$$jacoboooometeor";
//按重复字符分割字符串
Stringregex3="(.)\\1+";
split(str1,regex1);
split(str2,regex2);
split(str3,regex3);
}
publicstaticvoidsplit(Stringstr,Stringregex){
String[]arr=str.split(regex);
for(Stringstring:arr){
System.out.print(string+"|");
}
System.out.println();
}


3.替代

方法

StringreplaceAll(Stringregex,Stringreplacement)
StringreplaceFirst(Stringregex,Stringreplacement)

示例

Stringstr1="itheima######java&&&&&&&meteor";
//将将叠词替换成"-"
str1=str1.replaceAll("(.)\\1+","-");
Stringstr2="itheima######java&&&&&&&meteor";
//将将叠词替换成其中的一个,多个######用#替换。
//当在第二个参数中使用第一个正则参数中的组时,可以使用$编号来完成组的调用。\\1只能使用在正则表达式中。
str2=str2.replaceAll("(.)\\1+","$1");
Stringstr3="13988887777";
//将电话中的中间四位替换成****;
str3=str3.replaceAll("(\\d{3})(\\d{4})(\\d{4})","$1****$3");



正则表达式相关API

1.Pattern类(java.util.regex)

概述

正则表达式的编译表现形式,每一个正则表达式在编译后都是一个Pattern对象。该类无构造器,使用静态方法编译正则表达式获取实例。Pattern的作用是将正则字符串封装成正则对象。

方法

编译正则表达式

staticPatterncompile(Stringregex)
按正则表达式获取匹配输入的匹配器

Matchermatcher(CharSequenceinput)
按给定正则表达式匹配字符序列

staticbooleanmatches(Stringregex,CharSequenceinput)
获取该正则表达式

Stringpattern()
按正则表达式分割字符序列

String[]split(CharSequenceinput)

String[]split(CharSequenceinput,intlimit)

2.Matcher类(java.util.regex)

概述

字符串与正则表达式的匹配表现形式,起作用就是将字符串和正则表达式的匹配封装成对象。该类无构造器,一般通过Pattern类实例创建匹配器实例。

方法

匹配下一处

booleanfind()
重置匹配器,从start开始匹配下一处

booleanfind(intstart)
获取先前已经匹配的字符串

Stringgroup()
获取匹配成功的次数

intgroupCount()
从区域开头开始匹配

booleanlookingAt()
整个区域进行匹配

booleanmatches()
获取该匹配器的正则表达式对象

Patternpattern()
对匹配器的区域进行限制

Matcherregion(intstart,intend)
全部替换

StringreplaceAll(Stringreplacement)
替换匹配第一处

StringreplaceFirst(Stringreplacement)
重置匹配器

Matcherreset()
使用新的字符序列重置匹配器

Matcherreset(CharSequenceinput)
获取上一次匹配的开始索引

intstart()

3.匹配步骤

将正则表达式的字符串格式先通过Pattern中的compile方法编译成Pattern正则表达式对象。

Patternp=Pattern.compile("a*b");
要想用这个规则对字符串进行操作,还需要通过正则对象matcher方法和指定的字符串关联,并获取匹配器对象Matcher。

Matcherm=p.matcher("aaaaab");
用匹配器对象Matcher的功能(方法)对字符串进行操作。

一般使用matches(),find(),lookingAt(),start(),end(),等方法。

4.示例

packageregex;
importjava.util.regex.Matcher;
importjava.util.regex.Pattern;
publicclassPatternDemo{
publicstaticvoidmain(String[]args){
//需求:获取字符串中由10个字母及以上组成的单词。
Stringstr=
"BackslasheswithinstringliteralsinJavasourcecodeareinterpretedasrequired"
+"byTheJavaLanguageSpecificationaseitherUnicodeescapes(section3.3)orother"
+"characterescapes(section3.10.6)Itisthereforenecessarytodoublebackslashes"
+"instringliteralsthatrepresentregularexpressionstoprotectthemfrom"
+"interpretationbytheJavabytecodecompiler.Thestringliteralb,"
+"forexample,matchesasinglebackspacecharacterwheninterpretedasaregular"
+"expression,whilebmatchesawordboundary.Thestringliteral(hello)isillegal"
+"andleadstoacompile-timeerror;inordertomatchthestring(hello)thestring"
+"literal(hello)mustbeused.";
//定义规则。
Stringregex="\\b[a-zA-Z]{10,}\\b";
//1.将正则字符串编译成正则对象。
Patternp=Pattern.compile(regex);
//2.将正则对象和字符串相关联,并获取匹配器。
Matcherm=p.matcher(str);
//3.使用find的方法
/*
*m.lookingAt()方法从头匹配正则表达式一次。
*m.start()和m.end()分别能够获取匹配字符串的头尾索引值。
*/
while(m.find()){
System.out.println(m.group());
}
}
}



案例

1.常见匹配

packageregex;
importjava.util.Arrays;
publicclassText_Regex{
publicstaticvoidmain(String[]args){
//需求1:匹配电子邮箱
matchEmail();
/*
*需求2:
*把“我我.....我我.我....我.要.要要.....要.要学....学...学学....学.学编..编....编..编.编.程程.程...
*..程.程程”
*还原成:我要学编程。
*/
replace();
/*
*需求3:
*127.0.0.13.3.3.3192.168.104.2310.10.10.10
*要求按照ip地址的分类进行从小到大的排序。
*/
sortIP();
}
publicstaticvoidsortIP(){
/*
*思路:
*由于需要按照数字排序,而字符串排序方式为字典顺序排序,所以先补零以获得同等长度IP地址字符串,再排序,最后还原。
*/
Stringip="127.0.0.13.3.3.3192.168.104.2310.10.10.10";
ip=ip.replaceAll("(\\d+)","00$1");
ip=ip.replaceAll("0*(\\d{3})","$1");
String[]ips=ip.split("\\s+");
Arrays.sort(ips);
for(Stringstring:ips){
string=string.replaceAll("0*(\\d+)","$1");
System.out.println(string);
}
}
publicstaticvoidreplace(){
Stringstr="我我.....我我.我....我.要.要要.....要.要学....学...学学....学.学编..编....编..编.编.程程.程.....程.程程";
str=str.replaceAll("\\.+","");
str=str.replaceAll("(.)\\1+","$1");
System.out.println(str);
}
publicstaticvoidmatchEmail(){
Stringemail="jacobvv@163.com";
Stringregex="\\w+@[a-zA-Z0-9]+(\\.[a-zA-Z]+){1,3}";
booleanb=email.matches(regex);
System.out.println(b);
}
}


2.网络爬虫

packageregex;
importjava.io.BufferedReader;
importjava.io.IOException;
importjava.io.InputStreamReader;
importjava.net.URL;
importjava.net.URLConnection;
importjava.util.HashSet;
importjava.util.Set;
importjava.util.regex.Matcher;
importjava.util.regex.Pattern;
publicclassText_NetSpider{
publicstaticvoidmain(String[]args){
/*
*需求:网络爬虫
*获取某网页上的所有邮箱地址
*/
Stringurl="http://tieba.baidu.com/p/2720132008";
Set<String>email=null;
try{
email=getEmail(url);
}catch(IOExceptione){
e.printStackTrace();
}
for(Stringstring:email){
System.out.println(string);
}
}
publicstaticSet<String>getEmail(StringurlStr)throwsIOException{
Set<String>email=newHashSet<String>();
Stringregex="\\w+@[a-zA-Z0-9]+(\\.[a-zA-Z]+){1,3}";
Patternp=Pattern.compile(regex);
URLurl=newURL(urlStr);
URLConnectionconn=url.openConnection();
BufferedReaderbr=newBufferedReader(newInputStreamReader(conn.getInputStream()));
Stringcontent=null;
while((content=br.readLine())!=null){
Matcherm=p.matcher(content);
while(m.find()){
email.add(m.group());
}
}
br.close();
returnemail;
}
}


1.概述

正则表达式是用于描述字符串复杂规则的工具,换句话说,正则表达式就是记录文本规则的代码。

2.优势与劣势

优势:用了一些符号来代表这些代码,书写起来更为简单。

劣势:因为都是一些符号组成的表达式,所以阅读起来可读性不高,而且先要把符号学完。

3.格式

3.1元字符

.匹配除换行符以外的任意字符
\w匹配字母或数字或下划线或汉字
\s匹配任意的空白符
\d匹配数字
\b匹配单词的开始或结束
^匹配字符串的开始
$匹配字符串的结束

示例

\b\w\w\b:匹配由2个字母构成的单词。(Java字符串中为"\\b\\w\\w\\b")

3.2限定符

*重复零次或更多次
+重复一次或更多次
?重复零次或一次
{n}重复n次
{n,}重复n次或更多次
{n,m}重复n到m次

示例

\ba\w*\b:匹配以字母a开头的单词。(Java字符串中为"\\ba\\w*\\b")
\d+:匹配1个或更多连续的数字。(Java字符串中为"\\d+")
\b\w{6}\b:匹配刚好6个字符的单词。(Java字符串中为"\\b\\w{6}\\b")

3.3字符与字符转义

单个字符的判断可以使用集合概念,只需使用"[]"即可,例如:"[aeiou]"匹配任何一个英文元音字母。
在Java字符串中,由于字符"\"本身具有转义性,所以凡是带有"\"的正则表达式,均需要使用"\\"来替代"\"。例如上述例子"\d+"在Java字符串中应写成"\\d+"。
如果需要匹配正则表达式中有特殊意义的字符本身,需要使用"\"进行转义。例如可以使用正则表达式"\\w*\.\\w*"来匹配"abc.com"。

示例

\(?0\d{2,3}[)-]?\d{7,8}:匹配几种格式的电话号码,类似(010)88886666,或0554-22334455,或05541234567等。

3.4分支条件(逻辑或)

如果多种情况需要匹配,可以使用"|"将多种正则表达式连接在一起成为一个,任何满足其中一个正则表达式即可匹配。

示例

0\d{2}-\d{8}|0\d{3}-\d{7}:匹配两种以连字号分隔的电话号码:一种是三位区号,8位本地号(如010-12345678),一种是4位区号,7位本地号(0376-2233445)。

3.5分组

如果需要对多个字符进行重复或者在Java字符串中进行替换处理,可以使用分组,符号为"()"。
Java字符串处理中,使用"\数字"来代替前面的第几个分组,例如"(.)\\1+"匹配出现连续相同字符。

示例

(\d{1,3}\.){3}\d{1,3}:简单的IP地址匹配表达式,但是类似"111.222.666.999"的IP地址也视为匹配。
((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?):IP地址匹配表达式,由于正则表达式不支持数学运算和比较,所以只能使用繁杂的分组和分支来实现。

3.6反义

\W匹配任意不是字母,数字,下划线,汉字的字符
\S匹配任意不是空白符的字符
\D匹配任意非数字的字符
\B匹配不是单词开头或结束的位置
[^x]匹配除了x以外的任意字符
[^aeiou]匹配除了aeiou这几个字母以外的任意字符

示例

\S+:匹配不包含空白符的字符串。


字符串(String类)

1.匹配

方法

booleanmatches(Stringregex)

示例

Stringnum="13988887777\nhaha";
StringnumRegex="[1][3578]\\d{9}";//匹配手机号码
booleanb=num.matches(numRegex);


2.分割

方法

String[]split(Stringregex)
String[]split(Stringregex,intlimit)

示例

publicstaticvoidsplit(){
Stringstr1="itheima.java.jacob.meteor";
//按“.”分割字符串
Stringregex1="\\.";
Stringstr2="itheimajavajacob\tmeteor";
//按空白字符分割字符串
Stringregex2="\\s+";
Stringstr3="itheimaeeejava$$jacoboooometeor";
//按重复字符分割字符串
Stringregex3="(.)\\1+";
split(str1,regex1);
split(str2,regex2);
split(str3,regex3);
}
publicstaticvoidsplit(Stringstr,Stringregex){
String[]arr=str.split(regex);
for(Stringstring:arr){
System.out.print(string+"|");
}
System.out.println();
}


3.替代

方法

StringreplaceAll(Stringregex,Stringreplacement)
StringreplaceFirst(Stringregex,Stringreplacement)

示例

Stringstr1="itheima######java&&&&&&&meteor";
//将将叠词替换成"-"
str1=str1.replaceAll("(.)\\1+","-");
Stringstr2="itheima######java&&&&&&&meteor";
//将将叠词替换成其中的一个,多个######用#替换。
//当在第二个参数中使用第一个正则参数中的组时,可以使用$编号来完成组的调用。\\1只能使用在正则表达式中。
str2=str2.replaceAll("(.)\\1+","$1");
Stringstr3="13988887777";
//将电话中的中间四位替换成****;
str3=str3.replaceAll("(\\d{3})(\\d{4})(\\d{4})","$1****$3");



正则表达式相关API

1.Pattern类(java.util.regex)

概述

正则表达式的编译表现形式,每一个正则表达式在编译后都是一个Pattern对象。该类无构造器,使用静态方法编译正则表达式获取实例。Pattern的作用是将正则字符串封装成正则对象。

方法

编译正则表达式

staticPatterncompile(Stringregex)
按正则表达式获取匹配输入的匹配器

Matchermatcher(CharSequenceinput)
按给定正则表达式匹配字符序列

staticbooleanmatches(Stringregex,CharSequenceinput)
获取该正则表达式

Stringpattern()
按正则表达式分割字符序列

String[]split(CharSequenceinput)

String[]split(CharSequenceinput,intlimit)

2.Matcher类(java.util.regex)

概述

字符串与正则表达式的匹配表现形式,起作用就是将字符串和正则表达式的匹配封装成对象。该类无构造器,一般通过Pattern类实例创建匹配器实例。

方法

匹配下一处

booleanfind()
重置匹配器,从start开始匹配下一处

booleanfind(intstart)
获取先前已经匹配的字符串

Stringgroup()
获取匹配成功的次数

intgroupCount()
从区域开头开始匹配

booleanlookingAt()
整个区域进行匹配

booleanmatches()
获取该匹配器的正则表达式对象

Patternpattern()
对匹配器的区域进行限制

Matcherregion(intstart,intend)
全部替换

StringreplaceAll(Stringreplacement)
替换匹配第一处

StringreplaceFirst(Stringreplacement)
重置匹配器

Matcherreset()
使用新的字符序列重置匹配器

Matcherreset(CharSequenceinput)
获取上一次匹配的开始索引

intstart()

3.匹配步骤

将正则表达式的字符串格式先通过Pattern中的compile方法编译成Pattern正则表达式对象。

Patternp=Pattern.compile("a*b");
要想用这个规则对字符串进行操作,还需要通过正则对象matcher方法和指定的字符串关联,并获取匹配器对象Matcher。

Matcherm=p.matcher("aaaaab");
用匹配器对象Matcher的功能(方法)对字符串进行操作。

一般使用matches(),find(),lookingAt(),start(),end(),等方法。

4.示例

packageregex;
importjava.util.regex.Matcher;
importjava.util.regex.Pattern;
publicclassPatternDemo{
publicstaticvoidmain(String[]args){
//需求:获取字符串中由10个字母及以上组成的单词。
Stringstr=
"BackslasheswithinstringliteralsinJavasourcecodeareinterpretedasrequired"
+"byTheJavaLanguageSpecificationaseitherUnicodeescapes(section3.3)orother"
+"characterescapes(section3.10.6)Itisthereforenecessarytodoublebackslashes"
+"instringliteralsthatrepresentregularexpressionstoprotectthemfrom"
+"interpretationbytheJavabytecodecompiler.Thestringliteralb,"
+"forexample,matchesasinglebackspacecharacterwheninterpretedasaregular"
+"expression,whilebmatchesawordboundary.Thestringliteral(hello)isillegal"
+"andleadstoacompile-timeerror;inordertomatchthestring(hello)thestring"
+"literal(hello)mustbeused.";
//定义规则。
Stringregex="\\b[a-zA-Z]{10,}\\b";
//1.将正则字符串编译成正则对象。
Patternp=Pattern.compile(regex);
//2.将正则对象和字符串相关联,并获取匹配器。
Matcherm=p.matcher(str);
//3.使用find的方法
/*
*m.lookingAt()方法从头匹配正则表达式一次。
*m.start()和m.end()分别能够获取匹配字符串的头尾索引值。
*/
while(m.find()){
System.out.println(m.group());
}
}
}



案例

1.常见匹配

packageregex;
importjava.util.Arrays;
publicclassText_Regex{
publicstaticvoidmain(String[]args){
//需求1:匹配电子邮箱
matchEmail();
/*
*需求2:
*把“我我.....我我.我....我.要.要要.....要.要学....学...学学....学.学编..编....编..编.编.程程.程...
*..程.程程”
*还原成:我要学编程。
*/
replace();
/*
*需求3:
*127.0.0.13.3.3.3192.168.104.2310.10.10.10
*要求按照ip地址的分类进行从小到大的排序。
*/
sortIP();
}
publicstaticvoidsortIP(){
/*
*思路:
*由于需要按照数字排序,而字符串排序方式为字典顺序排序,所以先补零以获得同等长度IP地址字符串,再排序,最后还原。
*/
Stringip="127.0.0.13.3.3.3192.168.104.2310.10.10.10";
ip=ip.replaceAll("(\\d+)","00$1");
ip=ip.replaceAll("0*(\\d{3})","$1");
String[]ips=ip.split("\\s+");
Arrays.sort(ips);
for(Stringstring:ips){
string=string.replaceAll("0*(\\d+)","$1");
System.out.println(string);
}
}
publicstaticvoidreplace(){
Stringstr="我我.....我我.我....我.要.要要.....要.要学....学...学学....学.学编..编....编..编.编.程程.程.....程.程程";
str=str.replaceAll("\\.+","");
str=str.replaceAll("(.)\\1+","$1");
System.out.println(str);
}
publicstaticvoidmatchEmail(){
Stringemail="jacobvv@163.com";
Stringregex="\\w+@[a-zA-Z0-9]+(\\.[a-zA-Z]+){1,3}";
booleanb=email.matches(regex);
System.out.println(b);
}
}


2.网络爬虫

packageregex;
importjava.io.BufferedReader;
importjava.io.IOException;
importjava.io.InputStreamReader;
importjava.net.URL;
importjava.net.URLConnection;
importjava.util.HashSet;
importjava.util.Set;
importjava.util.regex.Matcher;
importjava.util.regex.Pattern;
publicclassText_NetSpider{
publicstaticvoidmain(String[]args){
/*
*需求:网络爬虫
*获取某网页上的所有邮箱地址
*/
Stringurl="http://tieba.baidu.com/p/2720132008";
Set<String>email=null;
try{
email=getEmail(url);
}catch(IOExceptione){
e.printStackTrace();
}
for(Stringstring:email){
System.out.println(string);
}
}
publicstaticSet<String>getEmail(StringurlStr)throwsIOException{
Set<String>email=newHashSet<String>();
Stringregex="\\w+@[a-zA-Z0-9]+(\\.[a-zA-Z]+){1,3}";
Patternp=Pattern.compile(regex);
URLurl=newURL(urlStr);
URLConnectionconn=url.openConnection();
BufferedReaderbr=newBufferedReader(newInputStreamReader(conn.getInputStream()));
Stringcontent=null;
while((content=br.readLine())!=null){
Matcherm=p.matcher(content);
while(m.find()){
email.add(m.group());
}
}
br.close();
returnemail;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: