java 正则(4) 不常用 / 贪婪匹配 / 非捕获组 / 向前引用 / flag 简写

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















C
ct
ct
C
a
ac
act
acti
activ
activi
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值