1.以下用的不多,正则前三个内容已经够用,以下掌握不了也没关系,论坛上有人用,能看懂就行。
贪婪匹配 :Greedy ,用在数量词( 比如 * 之后加个问号,或者 {3,5} 这个后面加个问号 )之后,例如点星,就是贪婪匹配,点星问,就是非贪婪。也就是说,贪婪就是默认的
/ 非捕获组 :其中 ?= 用的算相对较多的
/ 向前引用 :用的极少 \\1 \\2 这种写法
/ flag 简写 : ? i 是CASE_INSENSITIVE 的简写
//之前的正则内容已经能够解决大部分问题,以下是额外的正则表达式内容,比较高级,qulifiers修饰符,限定符,是API 文档Pattern 中的 数量词
/**
* Greedy 数量词 ,即贪婪的数量词。默认的写法都是Greedy 数量词
* Reluctant 数量词,勉强,不情愿的数量词
* Possessive 数量词,占有欲,独占的数量词,用的非常少。这种就是挑最大的吞(这里是{3,10},故吞10个),不吐,所以效率高,追求效率的时候,用这种
* 以上三种有着非常细小的差别,Pattern 类里面有具体说明,这些都是量词,都跟在 + ? * 这种量词之后
*/
public static void greedyRegex(){//贪婪正则
//测试 qulifiers,以下是Greedy,贪婪的
System.out.println("---------higherRegex---------");
Pattern p = Pattern.compile("(.{3,10})[0-9]");//0-10,注意这里不用()进行组控制,能实现贪婪,只是这样看得清楚。<span style="color:#ff0000;">这里的大括号{3,10}是量词</span>
String s = "aaaa5bbbb6";//贪婪是,吃最多的,.{3,10}这个整体,先吃进去10个字符,发现整体不合适,[0,-9]这个数字不匹配,故吐出去一个6,
Matcher m = p.matcher(s);//而后,匹配了,故出结果0-10
if(m.find())
System.out.println("Greedy is "+m.start()+"-"+m.end());
else
System.out.println("not match");
//以下是 reluctant,勉强的,不情愿的
p = Pattern.compile("(.{3,10}?)[0-9]");//0-5
s = "aaaa5bbbb6";//勉强的,不情愿的,是吃最少的,.{3,10}这个整体,先吃进去3个字符aaa,一看不合适,继续吃,迟到第4个,发现合适了,故出结果
m = p.matcher(s);
if(m.find())
System.out.println("reluctant is "+m.start()+"-"+m.end());
else
System.out.println("not match");
//以下是 Possessive 1
p = Pattern.compile("(.{3,10}+)[0-9]");//not match
s = "aaaa5bbbb6";//这个和贪婪的有点类似,他上来全吞进去,但是不往外吐,吞进去后发现不匹配,因为字符串aaaa5bbbb6后面都没有东西了,所以
m = p.matcher(s);//不匹配,
if(m.find())
System.out.println("reluctant is "+m.start()+"-"+m.end());
else
System.out.println("not match");
//以下是 Possessive 2
p = Pattern.compile("(.{3,10}+)[0-9]");//0-11
s = "aaaa5bbbb68";//一下子吞进10个即aaaa5bbbb6,此时后面是8,故字符串整体和正则匹配,所以返回0-11
m = p.matcher(s);//
if(m.find())
System.out.println("reluctant is "+m.start()+"-"+m.end());
else
System.out.println("not match");
}
//non-capturing groups 用的比较少,只有(?=a) 算是非捕获组用的多的,因为这种非捕获组的写法可以完全被别的替代,但是别人这么写用能读懂,perl 中常用
public static void nonCapturingGroup(){
System.out.println("----------nonCapturingGroup----------");
Pattern p = Pattern.compile(".{3}(?=a)");//正常情况,小括号里面是个组,这个组用来匹配字符串,
//但是此时,小括号里面以问号打头的,他不是用来匹配字符串的,所以他叫non capturing,不捕获字符串
String s = "444a66b"; //这叫非捕获组,意思是我抓三个字符加a结尾的字符串,但是我不捕获a,也就是只返回给三个字符,即结果是 444
Matcher m = p.matcher(s); //如果写正则是 (?=a).{3},则打印a66,所以(?=a) 写前面和后面不一样,?=写前面是把a 算在结果之中,
while(m.find()){ //?=写后面是把a 不算在结果之中,所以他叫lookahead,从头开始看,尾巴上不算
//System.out.println(m.group());
}
//以下非常不常用
p = Pattern.compile("(?!=a).{3}");//意思是前面不能为a的,结果是444 66b
p = Pattern.compile(".{3}(?!=a)");//意思是后面跟着的不是a, 结果是44a 66b
p = Pattern.compile(".{3}(?<=a)");
s = "444a66b";
m = p.matcher(s);
while(m.find()){
System.out.println(m.group());//.{3}(?<!=a) 444,a66,意思是从后往前数不能是a的 .{3}(?<=a)是44a 从后往前数是a的 ,而且还包含a
}
}
//back reference 向前引用,用的很少
public static void backReference(){
Pattern p = Pattern.compile("(\\d\\d\\1)");
String s = "1212";//true , 向前引用,和第一组要能完全匹配,12和12完全一样,true
Matcher m = p.matcher(s);
System.out.println(m.matches());
p = Pattern.compile("(\\d(\\d)\\2)");//向前引用,和第二组要能完全匹配,2和前面第二组的2完全匹配,true
s = "122";//true
//flags 只有CASE_INSENSITIVE flag 常用,CASE_INSENSITIVE 简写为?i
//Pattern p = Pattern.compile("java",Pattern.CASE_INSENSITIVE);
System.out.println("Java".matches("(?i)(java)"));//true 写法同上
}
2. 一个贪婪的例子
代码为:
if(line.contains("/actity/srch")){
temp1 = line.split("200 OK");
temp2 = temp1[0].split(".*?:\\d{1,5}");//点星问,这种是reluctant 非贪婪,点星是默认写法,贪婪
//split 是用正则这个整体去分割字符串,整体不出现在字符串中
IPSetTemp.add(temp2[temp2.length-1].trim());
}
line 为:
#2016-03-09 00:00:00.860 /100.8.91.5:800/100.8.110.11:6044 100.15.99.31200 OK 4805 434POST false/actity/srch?requestFormat=xml&responseFormat=xmlHTTP/1.1 Content-Type:application/x-www-form-urlencoded;Host:ws.activi.search.rirp.com;Content-Length:434;Expect:100-continue;Connection:Close;X-Forwarded-For:10.15.99.3;Netty-Client-IP:100.8.110.11;Content-Length:805;Content-Length-Bytes:805;Search
temp1 为:有两个
#2016-03-09 00:00:00.860 /100.8.91.5:800/100.8.110.11:6044 100.15.99.31
4 805 434POST false/actity/srch?requestFormat=xml&responseFormat=xmlHTTP/1.1 Content-Type:application/x-www-form-urlencoded;Host:ws.activi.search.rirp.com;Content-Length:434;Expect:100-continue;Connection:Close;X-Forwarded-For:10.15.99.3;Netty-Client-IP:100.8.110.11;Content-Length:805;Content-Length-Bytes:805;Search-Total:329;Search
temp2 为:若被贪婪分 .*:\\d{1,5} 则为
"" 即空
10.15.99.3
temp2 若被reluctant 分 .*?:\\d{1,5} 则分成5个,则为
"" 即空
"" 即空
"" 即空
"" 即空
10.15.99.3