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

java中正则表达式以及Pattern和Matcher

2017-05-29 10:21 453 查看
正则匹配

// 反斜杠

/t 间隔 ('/u0009')

/n 换行 ('/u000A')

/r 回车 ('/u000D')

/d 数字 等价于[0-9]

/D 非数字 等价于[^0-9]

/s 空白符号 [/t/n/x0B/f/r]

/S 非空白符号 [^/t/n/x0B/f/r]

/w 单独字符 [a-zA-Z_0-9]

/W 非单独字符 [^a-zA-Z_0-9]

/f 换页符

/e Escape

/b 一个单词的边界

/B 一个非单词的边界

/G 前一个匹配的结束

^为限制开头

^java     条件限制为以Java为开头字符

$为限制结尾

java$     条件限制为以java为结尾字符

.  条件限制除/n以外任意一个单独字符

java..     条件限制为java后除换行外任意两个字符

加入特定限制条件「[]」

[a-z]     条件限制在小写a to z范围中一个字符

[A-Z]     条件限制在大写A to Z范围中一个字符

[a-zA-Z] 条件限制在小写a to z或大写A to Z范围中一个字符

[0-9]     条件限制在小写0 to 9范围中一个字符

[0-9a-z] 条件限制在小写0 to 9或a to z范围中一个字符

[0-9[a-z]] 条件限制在小写0 to 9或a to z范围中一个字符(交集)

[]中加入^后加再次限制条件「[^]」

[^a-z]     条件限制在非小写a to z范围中一个字符

[^A-Z]     条件限制在非大写A to Z范围中一个字符

[^a-zA-Z] 条件限制在非小写a to z或大写A to Z范围中一个字符

[^0-9]     条件限制在非小写0 to 9范围中一个字符

[^0-9a-z] 条件限制在非小写0 to 9或a to z范围中一个字符

[^0-9[a-z]] 条件限制在非小写0 to 9或a to z范围中一个字符(交集)

在限制条件为特定字符出现0次以上时,可以使用「*」

J*     0个以上J

.*     0个以上任意字符

J.*D     J与D之间0个以上任意字符

在限制条件为特定字符出现1次以上时,可以使用「+」

J+     1个以上J

.+     1个以上任意字符

J.+D     J与D之间1个以上任意字符

在限制条件为特定字符出现有0或1次以上时,可以使用「?」

JA?     J或者JA出现

限制为连续出现指定次数字符「{a}」

J{2}     JJ

J{3}     JJJ

文字a个以上,并且「{a,}」

J{3,}     JJJ,JJJJ,JJJJJ,???(3次以上J并存)

文字个以上,b个以下「{a,b}」

J{3,5}     JJJ或JJJJ或JJJJJ

两者取一「|」

J|A     J或A

Java|Hello     Java或Hello

 「()」中规定一个组合类型

比如,我查询<a href=/"index.html/">index</a>中<a href></a>间的数据,可写作<a.*href=/".*/">(.+?)</a>

在使用Pattern.compile函数时,可以加入控制正则表达式的匹配行为的参数:

Pattern Pattern.compile(String regex, int flag)

Pattern类和Matcher类

Java正则表达式通过java.util.regex包下的Pattern类与Matcher类实现(建议在阅读本文时,打开Java API文档,当介绍到哪个方法时,查看java API中的方法说明,效果会更佳). 

Pattern类用于创建一个正则表达式,也可以说创建一个匹配模式,它的构造方法是私有的,不可以直接创建,但可以通过Pattern.complie(String regex)简单工厂方法创建一个正则表达式, 

Java代码示例: 

Pattern p=Pattern.compile("\\w+"); 

p.pattern();//返回 \w+ 

pattern() 返回正则表达式的字符串形式,其实就是返回Pattern.complile(String regex)的regex参数 

1.Pattern.split(CharSequence input) 

Pattern有一个split(CharSequence input)方法,用于分隔字符串,并返回一个String[]

Java代码示例: 

Pattern p=Pattern.compile("\\d+"); 

String[] str=p.split("我的QQ是:456456我的电话是:0532214我的邮箱是:aaa@aaa.com"); 

结果:str[0]="我的QQ是:" str[1]="我的电话是:" str[2]="我的邮箱是:aaa@aaa.com" 

2.Pattern.matcher(String regex,CharSequence input)是一个静态方法,用于快速匹配字符串,该方法适合用于只匹配一次,且匹配全部字符串. 

Java代码示例: 

Pattern.matches("\\d+","2223");//返回true
Pattern.matches("\\d+","2223aa");//返回false,需要匹配到所有字符串才能返回true,这里aa不能匹配到
Pattern.matches("\\d+","22bb23");//返回false,需要匹配到所有字符串才能返回true,这里bb不能匹配到
3.Pattern.matcher(CharSequence input) 

说了这么多,终于轮到Matcher类登场了,Pattern.matcher(CharSequence input)返回一个Matcher对象. 

Matcher类的构造方法也是私有的,不能随意创建,只能通过Pattern.matcher(CharSequence input)方法得到该类的实例. 

Pattern类只能做一些简单的匹配操作,要想得到更强更便捷的正则匹配操作,那就需要将Pattern与Matcher一起合作.Matcher类提供了对正则表达式的分组支持,以及对正则表达式的多次匹配支持. 

Java代码示例: 

Pattern p=Pattern.compile("\\d+"); 

Matcher m=p.matcher("22bb23"); 

m.pattern();//返回p 也就是返回该Matcher对象是由哪个Pattern对象的创建的 

4.Matcher.matches()/ Matcher.lookingAt()/ Matcher.find() 

Matcher类提供三个匹配操作方法,三个方法均返回boolean类型,当匹配到时返回true,没匹配到则返回false 

matches()对整个字符串进行匹配,只有整个字符串都匹配了才返回true 

Java代码示例: 

Pattern p=Pattern.compile("\\d+");
Matcher m=p.matcher("22bb23");
m.matches();//返回false,因为bb不能被\d+匹配,导致整个字符串匹配未成功.
Matcher m2=p.matcher("2223");
m2.matches();//返回true,因为\d+匹配到了整个字符串
我们现在回头看一下Pattern.matcher(String regex,CharSequence input),它与下面这段代码等价 

Pattern.compile(regex).matcher(input).matches() 

lookingAt()对前面的字符串进行匹配,只有匹配到的字符串在最前面才返回true 

Java代码示例: 
Pattern p=Pattern.compile("\\d+");
Matcher m=p.matcher("22bb23");
m.lookingAt();//返回true,因为\d+匹配到了前面的22
Matcher m2=p.matcher("aa2223");
m2.lookingAt();//返回false,因为\d+不能匹配前面的aa
find()对字符串进行匹配,匹配到的字符串可以在任何位置. 

Java代码示例: 
Pattern p=Pattern.compile("\\d+");
Matcher m=p.matcher("22bb23");
m.find();//返回true
Matcher m2=p.matcher("aa2223");
m2.find();//返回true
Matcher m3=p.matcher("aa2223bb");
m3.find();//返回true
Matcher m4=p.matcher("aabb");
m4.find();//返回false
5.Mathcer.start()/ Matcher.end()/ Matcher.group() 

当使用matches(),lookingAt(),find()执行匹配操作后,就可以利用以上三个方法得到更详细的信息. 

start()返回匹配到的子字符串在字符串中的索引位置. 

end()返回匹配到的子字符串的最后一个字符在字符串中的索引位置. 

group()返回匹配到的子字符串 

Java代码示例:
Pattern p=Pattern.compile("\\d+");
Matcher m=p.matcher("aaa2223bb");
m.find();//匹配2223
m.start();//返回3
m.end();//返回7,返回的是2223后的索引号
m.group();//返回2223

Mathcer m2=m.matcher("2223bb");
m.lookingAt();   //匹配2223
m.star
4000
t();   //返回0,由于lookingAt()只能匹配前面的字符串,所以当使用lookingAt()匹配时,start()方法总是返回0
m.end();   //返回4
m.group();   //返回2223

Matcher m3=m.matcher("2223bb");
m.matches();   //匹配整个字符串
m.start();   //返回0,原因相信大家也清楚了
m.end();   //返回6,原因相信大家也清楚了,因为matches()需要匹配所有字符串
m.group();   //返回2223bb
说了这么多,相信大家都明白了以上几个方法的使用,该说说正则表达式的分组在java中是怎么使用的. 
start(),end(),group()均有一个重载方法它们是start(int i),end(int i),group(int i)专用于分组操作,Mathcer类还有一个groupCount()用于返回有多少组. 

Java代码示例: 
Pattern p=Pattern.compile("([a-z]+)(\\d+)");
Matcher m=p.matcher("aaa2223bb");
m.find();   //匹配aaa2223
m.groupCount();   //返回2,因为有2组
m.start(1);   //返回0 返回第一组匹配到的子字符串在字符串中的索引号
m.start(2);   //返回3
m.end(1);   //返回3 返回第一组匹配到的子字符串的最后一个字符在字符串中的索引位置.
m.end(2);   //返回7
m.group(1);   //返回aaa,返回第一组匹配到的子字符串
m.group(2);   //返回2223,返回第二组匹配到的子字符串
现在我们使用一下稍微高级点的正则匹配操作,例如有一段文本,里面有很多数字,而且这些数字是分开的,我们现在要将文本中所有数字都取出来,利用java的正则操作是那么的简单. 

Java代码示例: 
Pattern p=Pattern.compile("\\d+");
Matcher m=p.matcher("我的QQ是:456456 我的电话是:0532214 我的邮箱是:aaa123@aaa.com");
while(m.find()) {
System.out.println(m.group());
}

输出:
456456
0532214
123

如将以上while()循环替换成
while(m.find()) {
System.out.println(m.group());
System.out.print("start:"+m.start());
System.out.println(" end:"+m.end());
}
则输出:
456456
start:6 end:12
0532214
start:19 end:26
123
start:36 end:39


加上一个自己写的代码例子:

不用看,只是自己做一些记录:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**学习正则表达式
* Created by Administrator on 2017/5/28.
*/
public class PatAndMac {
public static void main(String []args){
String a = "将来的我比现在好";
System.out.println(a.matches("将来的"));
String string = "192.168.10.1";
String rule = "\\d{1,3}\\.\\d{1,3}.\\d{1,3}.\\d{1,3}";
System.out.println("192.168.10.1".matches("\\d{1,3}.\\d{1,3}.\\d{1,3}.\\d{1,3}"));
Pattern.matches("192.168.10.1","\\d{1,3}.\\d{1,3}.\\d{1,3}.\\d{1,3}");
System.out.println("aa".matches("aa?"));//?表示0-1次
System.out.println("aar".matches("aar+"));//+表示1-N次
System.out.println("".matches("a*"));//*表示出现过0-N次
System.out.println("w".matches("."));
System.out.println("qasugg135".matches("[a-z]{6}[0-9]{3}"));
System.out.println("1642485710@qq.com".matches("[0-9]+@\\w+.(com|cn|org|io)"));
System.out.println("hello".matches("^h.*o$"));
Pattern pattern = Pattern.compile(rule);
Matcher matcher = pattern.matcher(string);
System.out.println("全字符串匹配--->"+matcher.matches());
pattern = Pattern.compile("[a-z]+");
matcher = pattern.matcher("ewqgu34");//12ewqgu34就返回false
System.out.println("前面的匹配--->"+matcher.lookingAt());
pattern = Pattern.compile("\\w+");
matcher = pattern.matcher("@#!##_");
System.out.println("任意位子的匹配:只要出现就好--->"+matcher.find());
pattern = Pattern.compile("\\d+");
matcher = pattern.matcher("436vgf12w1135");
if(matcher.find()){
System.out.println("start---->"+matcher.start());
System.out.println("end---->"+matcher.end());
System.out.println("group---->"+matcher.group());
}else {
System.out.println("不匹配呀");
}
if(matcher.lookingAt()){
System.out.println("start---->"+matcher.start());
System.out.println("end---->"+matcher.end());
System.out.println("group---->"+matcher.group());
}else {
System.out.println("不匹配呀");
}
if(matcher.matches()){
System.out.println("start---->"+matcher.start());
System.out.println("end---->"+matcher.end());
System.out.println("group---->"+matcher.group());
}else {
System.out.println("不匹配呀");
}

pattern = Pattern.compile("\\d+");
matcher = pattern.matcher("我的QQ是:456456 我的电话是:0532214 我的邮箱是:aaa123@aaa.com");
while(matcher.find()){
System.out.println("find是可以循环的~~~~~~~");
System.out.println("start:"+matcher.start()+"end:"+ matcher.end()+"group:"+ matcher.group());
}
pattern = Pattern.compile("[a-z]+\\d+");
matcher = pattern.matcher("gg12415hh");
/* matcher.find();
System.out.println(matcher.start(1));
System.out.println(matcher.end(1));
System.out.println(matcher.group(1));
System.out.println(matcher.group(2));
System.out.println(matcher.start(2));
System.out.println(matcher.end(2));*/
/* matcher.find();
System.out.println("数目:"+matcher.groupCount()+"呀:---->"+matcher.find()+"---"+matcher.find());*/
while(matcher.find()){
System.out.println(matcher.groupCount());
System.out.println("?"+matcher.group());
}

pattern = Pattern.compile("aoy*");
matcher = pattern.matcher("aoyyyyyyys5s");
System.out.println(matcher.lookingAt());
matcher = pattern.matcher("aoy");
System.out.println(matcher.matches());
/*pattern = Pattern.compile("(http://|https://){1}[\\w]+");//(http://|https://){1}[\w.:]+"
matcher = pattern.matcher("dsdsds<http://www.baidu.com_1>fdf");
StringBuffer buffer = new StringBuffer();
while(matcher.find()){
buffer.append(matcher.group());
System.out.println(buffer.toString());
}*/

/*pattern = Pattern.compile("\"(.+?)\"");
matcher = pattern.matcher("<a href=\"index.html\">主页</a>");
if(matcher.find())
System.out.println(matcher.group(1));*/
PatAndMac pam = new PatAndMac();
pattern = Pattern.compile("\\{\\}");
String []s = {"手机号码"};
// pam.replaceContent(pattern,"参数中的\"{}\"不能为空",s);
// System.out.println(s);

String param = "一个数字加上N个字母";
pattern = Pattern.compile("[0-9]{1}[a-zA-Z]+");
pam.rep(pattern,"2ag6f227574_iyf3uo你好呀",param);
}
private static String replaceContent(Pattern pattern,String content, String... params){
Matcher matcher = pattern.matcher(content);
StringBuffer sb = new StringBuffer();
Integer idx = 0;
while(matcher.find()) {
if(params != null && idx < params.length) {
System.out.println("true次数+1");
String pm = params[idx++];
matcher.appendReplacement(sb, (pm == null) ? "null" : pm);
}else{
System.out.println("false次数+1");
matcher.appendReplacement(sb, "null");
}
}
System.out.println(sb.toString());
matcher.appendTail(sb);
System.out.println(sb.toString());
return sb.toString();
}

private static void rep(Pattern pattern,String context,String param){
Matcher matcher = pattern.matcher(context);
StringBuffer sb = new StringBuffer();
while (matcher.find()){
matcher.appendReplacement(sb,param);
System.out.println(sb.toString());
}
matcher.appendTail(sb);
System.out.println(sb.toString());
}

}
输出:
false
true
true
true
true
true
true
true
true
全字符串匹配--->true
前面的匹配--->true
任意位子的匹配:只要出现就好--->true
start---->0
end---->3
group---->436
start---->0
end---->3
group---->436
不匹配呀
find是可以循环的~~~~~~~
start:6end:12group:456456
find是可以循环的~~~~~~~
start:19end:26group:0532214
find是可以循环的~~~~~~~
start:36end:39group:123
0
?gg12415
true
true
一个数字加上N个字母
一个数字加上N个字母一个数字加上N个字母
一个数字加上N个字母一个数字加上N个字母227574_iyf一个数字加上N个字母
一个数字加上N个字母一个数字加上N个字母227574_iyf一个数字加上N个字母你好呀
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息