您的位置:首页 > 移动开发

java 正则(3) matches() / find() / lookingAt / start end / replaceAll / appendReplacement / group(int)

2016-01-11 16:21 453 查看
1. Matcher 类的  matches() / find() / lookingAt / start end / replaceAll / appendReplacement / group(int)  方法。

replaceAll( ) 方法不需要配合matcher.find()使用。

appendReplacement( )方法配合着matcher.find()使用,appendReplacement( )方法比replaceAll( ) 方法好用,想替换谁就替换谁,想怎么替换就怎么替换。

group ( int )方法,告诉我们,正则表达式可以分组,用小括号。从1 开始查左小括号来确定group( ) 函数的参数取值。如果不加参数,则用整个正则去匹配。

matcher.matches() / lookingAt() 和 while(matcher.find()) 都是可以接着matcher.start() / matcher.end() / matcher.group() 使用的,

public static void matcherTest(){
System.out.println("-------matcherTest-------");
Pattern p = Pattern.compile("\\d{3,5}");
String s = "123-34345-234-00";
Matcher m = p.matcher(s);
//正则表达式引擎吃进去一个字符分析一个字符,过程是先1再2再3再- 发下横线已经不匹配pattern 了,但是注意,正则表达式引擎吃进去的字符就不会往出吐。
//1.所以Matcher 的matches()和find()之间会有影响,千万千万要小心,这也就是写m.reset()的原因。
System.out.println(m.matches()); // false,matcher() 是尝试将整个字符串与模式匹配。
m.reset();	//m.reset()意思是请你把吃掉的字符吐出来,恢复到原来的状态. 如果不加这句,则以下四个是true / true /false / false
System.out.println(m.find());//true find 是找子串而不是匹配整个字符串
System.out.println(m.find());//true 每次找到一个子串后,正则表达式引擎会把找到的子串(123-) 去掉,在剩余的子串(34345-234-00)中继续找
System.out.println(m.find()); //true
System.out.println(m.find()); //false
////////////////2.  lookingAt
System.out.println(m.lookingAt());//这个方法起的名字太差劲了.这个函数意思是每次都从字符串头上开始找
System.out.println(m.lookingAt());//所以这四个全都输出true,因为开头的123符合
System.out.println(m.lookingAt());
System.out.println(m.lookingAt());
////////////////3.  start end 也是配合着while(m.find()) / m.matches() / m.lookingAt() 使用的,这里代码没写循环为了说明find()不出来时,引用m.start()会报错。
m.reset();
System.out.println(m.find());//
System.out.println(m.start()+"-"+m.end());//0-3,也就是end 是找到的字符的后一个位置
System.out.println(m.find());//
System.out.println(m.start()+"-"+m.end());//只要找到了,就可以把找到的子串的起始位置和结束位置打印出来
System.out.println(m.find()); //
System.out.println(m.start()+"-"+m.end());//
System.out.println(m.find()); //
//System.out.println(m.start()+"-"+m.end());// m.find()没有找到返回false,这句则报错, java.lang.IllegalStateException: No match available
///////////////////////4. 字符串替换,matcher 的replaceAll 方法
Pattern pnew = Pattern.compile("java",Pattern.CASE_INSENSITIVE);//  启用不区分大小写的匹配。
Matcher mnew = pnew.matcher("java Java JAVa JaVa IloveJAVA you hateJava");//

//4-1 替换,要求把这里的语句所有含java不论大小写都转化成大写
String replaceResult = mnew.replaceAll("JAVA");//参数是需要替换成的字符串(replace后,新字符串中的东西)
System.out.println(replaceResult);//JAVA JAVA JAVA JAVA IloveJAVA you hateJAVA

//4-2 替换,要求是匹配到的结果,单数的替换成大写,双数的替换成小写
/**
*  由以下替换方式可看出,替换字符串的方式非常灵活,想替换成什么样就替换成什么样,想替换几个就替换几个。
*  这个比replaceAll 强大和灵活的多
*
*  printout
*  buf中的内容在本次替换之前是
buf中的内容在本次替换之后是before JAVA    注意看这里是匹配到的java 携同之前的不匹配字符before 都写到stringbuffer 里面
buf中的内容在本次替换之前是before JAVA
buf中的内容在本次替换之后是before JAVA java
buf中的内容在本次替换之前是before JAVA java
buf中的内容在本次替换之后是before JAVA java JAVA
buf中的内容在本次替换之前是before JAVA java JAVA
buf中的内容在本次替换之后是before JAVA java JAVA java
buf中的内容在本次替换之前是before JAVA java JAVA java
buf中的内容在本次替换之后是before JAVA java JAVA java IloveJAVA
buf中的内容在本次替换之前是before JAVA java JAVA java IloveJAVA
buf中的内容在本次替换之后是before JAVA java JAVA java IloveJAVA you hatejava  注意这里,但是最后的tail 没写到stringbuffer里
所以在最后要加一个appendTail 函数
*/
StringBuffer buf = new StringBuffer();
mnew = pnew.matcher("before java Java JAVa JaVa IloveJAVA you hateJava tail");//
replaceResult = "";
int i = 0 ;//记录偶数 / 基数 的常量
while(mnew.find()){
i++;
System.out.println("buf中的内容在本次替换之前是"+buf);
if(i%2 == 0)
mnew.appendReplacement(buf, "java");//添加一个用来做替换的StringBuffer,这个替换是替换当前找到的这个位置,
else if (i%2 != 0)
mnew.appendReplacement(buf, "JAVA");//第一个参数StringBuffer,这个是把最后的结果放到stringbuffer里面去,第二个参数是要替换成的字符串
System.out.println("buf中的内容在本次替换之后是"+buf);
}
mnew.appendTail(buf);//把 tail加到stringbuffer 里面
System.out.println(buf);//before JAVA java JAVA java IloveJAVA you hatejava tail

//5. 输出匹配组group()方法   m.group() 也是配合着while(m.find()) / m.matches() / m.lookingAt() 使用的  //小括号代表正则表达式的分组,用小括号在正则里面实现,要看分了几组,就看有几对小括号就行
Pattern pGroup = Pattern.compile("(\\d{3,5})([a-z]{2})");//这个正则表达式严格意义是三组(整个表达式也算一组),每个组有一个组号
String sGroup = "123aa-34345bb-234cc-00";				 //那么这个组号怎么体现呢?group(1)这个1就是符合我们第一组的那些子串
Matcher mGroup = pGroup.matcher(sGroup);
mGroup.reset();
while(mGroup.find()){  //以下分三次打印出来,第一次123aa   123  aa,循环第二次34345bb  34345bb bb  , 第三次循环打印  234cc   234   cc
System.out.println(mGroup.group(0));//group(0)打印出来,整个正则表达式所匹配到的那些子串,而group(1)打印出数字子串,group(2)打印出字母子串
System.out.println(mGroup.group(1));// 如果正则表达式特别复杂,小括号套小括号,这时候就查正则的左小括号就行了
System.out.println(mGroup.group(2));//从左边开始第一个左小括号是第一组,用group(1)即可,第二个左小括号是第二组
}

}

group( int )举例:注意这里group( int ) 在正则里和在replaceAll( )  函数中的$1 $2  一个道理

line  是

/hoatel/sech?AppID=1107&needDekens0=true&needT0=true&platform=app/IPhon/614.002&query0=CityIDs:28%20AND%20(:%22%e6%96%b0%e5%ae%bf%22%20OR%20fullname2:%22%e6%96%b0%e5%ae%bf%22)%20AND%20SourceType:OverseHotel&requestFormat=url&respseFormat=xml&return0=ID,score,name&spelleckAction0=research

p = Pattern.compile("(keyword:|fullname:|fullname2:)(.*?)(%20|&|\\)%20)");//这里面竖线是或者的意思,右括号加了转义
m = p.matcher(line);// 正则用于匹配红色部分
if(m.find())
keyword = m.group(2); //group(1)是第一个括号内的东西


keyword = m.group( ); //打印fullname2:%22%e6%96%b0%e5%ae%bf%22)%20

keyword = m.group(0);   //打印   fullname2:%22%e6%96%b0%e5%ae%bf%22)%20

keyword = m.group(1);   // 打印  fullname2:

keyword = m.group(2);   //打印   %22%e6%96%b0%e5%ae%bf%22
keyword=m.group(3);     //打印   )%20

与上面group(1) 等价的replaceAll( ) 方法如下

System.out.println( line.replaceAll(".*(keyword|fullname|fullname2):(.*?)(&|%20AND).*", "$2"));  //打印   %22%e6%96%b0%e5%ae%bf%22
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: