正则表达式知识详解之前后查找(环视) (java版示例)

正则表达式知识详解系列,通过代码示例来说明正则表达式知识 

源代码下载地址:http://download.csdn.net/detail/gnail_oug/9504094


示例功能:

1、通过向左、向右查找方式找出字符串中的数字

2、分组方式和环视方式提取url里的协议名

3、给字符串指定位置插入内容

4、匹配字符串中的电话号码

5、分步介绍如何将一个金额改为用逗号(,)方式显示

	/**
	 * 前后查找(环视)
	 * 前后查找中的前、后指模式与被查找文本的相对位置而言,左为前,右为后
	 * (?=) 肯定正序环视,向右
	 * (?!) 否定正序环视,向右
	 * (?<=)肯定逆序环视,向左
	 * (?<!)否定逆序环视,向左
	 * !表示否定,=表示肯定,<表示向左
	 * 向前查找模式的长度是可变的,它们可以包含.和+之类的元字符,向后查找模式只能是固定长度
	 * @date 2016-04-21 16:30:17
	 * @author sgl
	 */
	public static void lookaround(){
		String str="hello123world45hello678java9";
		//匹配数字
		//匹配左边不是数字的数字
		System.out.println("------左边不是数字  使用(?<=)------");
		Pattern p=Pattern.compile("(?<=\\D)\\d+");
		Matcher m=p.matcher(str);
		while(m.find()){
			System.out.println(m.group()+"   位置:["+m.start()+","+m.end()+"]");
		}
		System.out.println("------左边不是数字  使用(?<!)------");
		p=Pattern.compile("(?<!\\d)\\d+");
		m=p.matcher(str);
		while(m.find()){
			System.out.println(m.group()+"   位置:["+m.start()+","+m.end()+"]");
		}
		System.out.println("------左右两边都是数字 ------");
		p=Pattern.compile("(?<=\\d)\\d+(?=\\d)");
		m=p.matcher(str);
		while(m.find()){
			System.out.println(m.group()+"   位置:["+m.start()+","+m.end()+"]");
		}
		System.out.println("------左右两边都不是数字 ------");
		p=Pattern.compile("(?<!\\d)\\d+(?!\\d)");
		m=p.matcher(str);
		while(m.find()){
			System.out.println(m.group()+"   位置:["+m.start()+","+m.end()+"]");
		}
		
		//提取url里的协议名
		System.out.println("-----提取url里的协议名-------");
		str="http://www.baidu.com,https:www.apharbor.com,ftp://ftp.apharbor.com";
		//通过分组提取方式
		System.out.println("+++++++++++通过分组提取方式++++++++++++");
		p=Pattern.compile("(\\w+):");
		m=p.matcher(str);
		while(m.find()){
			System.out.println(m.group()+"   位置:["+m.start()+","+m.end()+"] 协议名:"+m.group(1));
		}
		//通过前后查找(环视)方式,通过与上面的比较,可以发现前后查找的好处是只返回需要的内容,不需要的内容不再返回
		System.out.println("+++++++++++通过前后查找(环视)方式++++++++++++");
		p=Pattern.compile("\\w+(?=:)");
		m=p.matcher(str);
		while(m.find()){
			System.out.println(m.group()+"   位置:["+m.start()+","+m.end()+"]");
		}
		//严格的说,前后查找匹配是有返回结果的,只是这个结果是一个位置(字节长度永远是0)而已,如上面的正则匹配的位
		//置是http的p字母和:之间的位置,通过下面的例子可以清楚看出
		System.out.println("++++++++++++查找一个位置并替换成*+++++++++++");
		//查找一个位置并替换成*,这个位置的前面是单词字符并且后面是:
		p=Pattern.compile("(?<=\\w+)(?=:)");
		m=p.matcher(str);
		while(m.find()){
			//注意m.group()获取的内容为空,m.start()和m.end()值一样
			System.out.println(m.group()+"   位置:["+m.start()+","+m.end()+"]");
		}
		System.out.println(m.replaceAll("*"));
		
		
		System.out.println("--------匹配五位数的电话---------");
		str="电话号码:15230022100,15236622140中国电信10000中国联通10010消费者投诉12315建设银行95533招商银行95555";
		//匹配五位数的电话,即匹配一个5位数,这个数左面不是数字右面也不是数字
		p=Pattern.compile("(?<!\\d)\\d{5}(?!\\d)");
		m=p.matcher(str);
		while(m.find()){
			System.out.println(m.group()+"   位置:["+m.start()+","+m.end()+"]");
		}
		
		System.out.println("--------将金额用逗号分开---------");
		str="123456789";//123,456,789
		//str="3456789";//3,456,789
		//将金额用逗号分开,即匹配一个位置,将逗号放到这个位置,实现方法分析如下:
		//1、找一个位置,这个位置右面有n个数字,即:\d+ 并且都是3的倍数,即:(\d{3})+  所以总的表达式为(?=(\d{3})+)
		p=Pattern.compile("(?=(\\d{3})+)");
		m=p.matcher(str);
		while(m.find()){
			//789一组找到一个位置,678一组找到一个位置....123一组找到一个位置
			System.out.println(m.group()+"   位置:["+m.start()+","+m.end()+"]");
		}
		System.out.println(m.replaceAll(","));//输出,1,2,3,4,5,6,789
		
		//2、上一步结果为,1,2,3,4,5,6,789,说明最后一个位置找对了,之所以还出现上面的情况是因为"123456789"中678也是三个数字
		//只是678后面还是数字,为了方便先把7前的位置加个逗号,str="123456,789",现在我们要找到第二个位置即3和4之间,观察会发现
		//456这一组数字后面不是数字,789后面也不是数字,所以我们给上面正则再加个条件即位置的右面有n个数字,并且都是3的倍数,并且
		//这n个数字后面不能是数字
		p=Pattern.compile("(?=(\\d{3})+(?!\\d))");
		m=p.matcher(str);
		while(m.find()){
			System.out.println(m.group()+"   位置:["+m.start()+","+m.end()+"]");
		}
		System.out.println(m.replaceAll(","));
		
		//3、第2步结果为,123,456,789,说明后两个位置都对了,但第一个逗号不应该有,也就是说如果该位置左侧要有数字,所以再加一个条件
		p=Pattern.compile("(?<=\\d)(?=(\\d{3})+(?!\\d))");
		m=p.matcher(str);
		while(m.find()){
			System.out.println(m.group()+"   位置:["+m.start()+","+m.end()+"]");
		}
		System.out.println(m.replaceAll(","));
		
	}

运行结果:

------左边不是数字  使用(?<=)------
123   位置:[5,8]
45   位置:[13,15]
678   位置:[20,23]
9   位置:[27,28]
------左边不是数字  使用(?<!)------
123   位置:[5,8]
45   位置:[13,15]
678   位置:[20,23]
9   位置:[27,28]
------左右两边都是数字 ------
2   位置:[6,7]
7   位置:[21,22]
------左右两边都不是数字 ------
123   位置:[5,8]
45   位置:[13,15]
678   位置:[20,23]
9   位置:[27,28]
-----提取url里的协议名-------
+++++++++++通过分组提取方式++++++++++++
http:   位置:[0,5] 协议名:http
https:   位置:[21,27] 协议名:https
ftp:   位置:[44,48] 协议名:ftp
+++++++++++通过前后查找(环视)方式++++++++++++
http   位置:[0,4]
https   位置:[21,26]
ftp   位置:[44,47]
++++++++++++查找一个位置并替换成*+++++++++++
   位置:[4,4]
   位置:[26,26]
   位置:[47,47]
http*://www.baidu.com,https*:www.apharbor.com,ftp*://ftp.apharbor.com
--------匹配五位数的电话---------
10000   位置:[32,37]
10010   位置:[41,46]
12315   位置:[51,56]
95533   位置:[60,65]
95555   位置:[69,74]
--------将金额用逗号分开---------
   位置:[0,0]
   位置:[1,1]
   位置:[2,2]
   位置:[3,3]
   位置:[4,4]
   位置:[5,5]
   位置:[6,6]
,1,2,3,4,5,6,789
   位置:[0,0]
   位置:[3,3]
   位置:[6,6]
,123,456,789
   位置:[3,3]
   位置:[6,6]
123,456,789








  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值