黑马程序员——正则表达式3:练习

------ Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

1  正则表达式应用总结

       在上一篇博客中,介绍了正则表达式可以用于处理字符串的四种操作:匹配、替换、分割,以及获取。那么在面对操作字符串的需求时,该如何从这些功能中作出选择呢?

匹配:如果只想知道该字符串是否符合指定的正则表达式规则,就使用匹配功能;

替换:想要将已有的字符串转换成另一个字符串,则使用替换功能;

分割:想要按照指定的规则将字符串变成多个字符串,则使用分割功能。获取不符合规则的子串。

获取:想要获取到符合指定正则表达式规则的子串时,使用获取功能。获取符合规则的子串。

以上就是对正则表达式功能应用的总结。

2  练习

需求1:将字符串“我我…我我…我要..要要…要要…学学学….学学…编编编…编程..程.程程…程…程”,修改为“我要学编程”。

思路:

       按照上述总结,由于该需求需要将现有字符串转换为另一个字符串,因此主要使用正则表达式的替换功能。

1.  先将字符串中的“.”去掉;

2.  再将多个重复汉字去掉。

代码1:

class RegexTest
{
	public static void main(String[] args)
	{
		String str = "我我...我我...我要..要要...要要...学学学....学学...编编编...编程..程.程程...程...程";
 
		//将“.”替换为空字符串
		str = str.replaceAll("\\.+", "");
 
		System.out.println(str);
 
		//将重复汉字
		str = str.replaceAll("(.)\\1+", "$1");
 
		System.out.println(str);
	}
}
执行结果为:

我我我我我要要要要要学学学学学编编编编程程程程程程

我要学编程

 

需求2:给出一个由5个IP地址组成的字符串“192.168.1.254102.49.23. 13 10.10.10.10 2.2.2.2 8.109.90.30”,每个IP地址之间用空格进行分隔。要求是将IP地址按照IP地址段的顺序进行排序。比如“2.xxx.xxx.xxx”应排在“10.xxx.xxx.xxx”之前,而“192.xxx.xxx.xxx”应排在最后。

思路

       主要的思路就是将每个IP地址字符串,按照字符串的自然顺序进行排序。     

1.  首先将给出的IP地址字符串通过空格分隔为5个单独的IP地址。

2.  为了能使IP字符串之间通过字符串自然顺序比较,而能够按照IP地址进行排序,为每个段位前补两个0,效果如下:

       002.002.002.002

       008.00109.0090.0030

       0010.0010.0010.0010

       00102.0049.0023.0013

       00192.00168.001.00254

3.  如果某个IP地址段位本身只有1个数字,那么补两个0正好达到3位;而如果某个IP地址本身就包含3个数字,此时就多出两位需要去掉,效果如下:

       002.002.002.002

       008.109.090.030

       010.010.010.010

       102.049.023.013

       192.168.001.254

4.  这样一来可以保证每个IP地址段位都包含3位数字,而不足3位的就用0填充。接着可以将以上5个IP地址字符串存入TreeSet集合,或者存入字符串数组,结合Arrays.sort方法进行排序即可。

代码2:

java.util.*;
 
class RegexTest2
{
	public static void main(String[] args)
	{
		String ips = "192.168.1.254102.49.23.13 10.10.10.10 2.2.2.2 8.109.90.30";
 
		//将IP地址字符串通过空格分割为单个IP
		String[] ipsBuf = ips.split(" ");
 
		String temp = null;
		for(int i=0; i<ipsBuf.length; i++){
			temp = ipsBuf[i];
                    
			//为每个地址段位添加两个0
			temp = temp.replaceAll("(\\d+)", "00$1");
			//将一些段位中多余的0去掉
			temp = temp.replaceAll("0*(\\d{3})", "$1");
 
			ipsBuf[i] = temp;
		}
 
		TreeSet<String> ts = new TreeSet<String>();
		for(int i=0; i<ipsBuf.length; i++){
			ts.add(ipsBuf[i]);
		}
 
		for(String ip : ts){
			//为了美观,将占位用的0也去除掉
			System.out.println(ip.replaceAll("0*(\\d+)","$1"));
		}
	}
}
执行结果为:

2.2.2.2

8.109.90.30

10.10.10.10

102.49.23.13

192.168.1.254

代码说明:

       (1)  在进行补零操作时,正则表达式“(\\d+)”的含义为,将匹配的1个或多个数字封装为一个组(也就是将一个段位数字封装为一个组),然后通过“$1”引用这个组的同时,再前面再添加2个0。

       (2)  在去0操作中,“0*(\\d{3})”的含义为,起初可能没有0,也可能有多个零,后面连续出现3个数字。以00192为例,起初有2个0,后面有三个数字,因此符合这一规则,就将00192替换为了192;若是002,则起初没有0,后面的的三个数字为0、0、2,因此就是002替换为了它本身。

       (3)  去占位0的操作中,“0*(\\d+)”含义为,起初可能没有0,也可能有多个0,后面有一个或多个数字。比如,以002为例,起初有2个0,后接一个2,因此就将002替换为2。

 

需求3:对邮件地址进行校验。以“abc123@sina.com”为例。要求“@”符号前的用户名在6-12位以内。

思路:

       显然,所有邮件地址的格式中都包含“@”符号,这是一个固定格式。因此对应的正则表达式中也应该包含这一符号。

       有的邮箱格式会在“.com”后接“.cn”,或者是“.edu.cn”等。对于一个“.com”我们可以定义匹配规则为:“\\.[a-zA-Z]+”,表示“.”后接1至多个字母(实际对应的就是.com)。若具有后接“.cn”的情况,可以将“\\.[a-zA-Z]+”封装为一个组,并定义该组可能出现一次或两次。

代码3:

class RegexTest
{
	public static void main(String[] args)
	{
		String[] mailAddresses = {"abc123@163.com", "564368845@qq.com", "haha@xxx.edu.cn",  "84568ttjhdreehrh4565@sina.com", "heihei@126.com.cn.cn"};
 
		Stringr egex = "[a-zA-Z0-9_]{6,12}@[a-zA-Z0-9]+(\\.[a-zA-Z]+){1,2}";
 
		for(String mailAddress : mailAddresses){
			System.out.println(mailAddress+": "+mailAddress.matches(regex));
		}
	}
}
执行结果为:

abc123@163.com : true

564368845@qq.com : true

haha@xxx.edu.cn : false

84568ttjhdreehrh4565@sina.com : false

heihei@126.com.cn.cn : false

代码说明:

       如果对于匹配要求并不十分精确的话,可以将以上代码中的“[a-zA-Z0-9]”,改为“\\w”,后者表示单词字符[a-zA-Z_0-9]。

 

需求4:模拟网页爬虫(蜘蛛)程序。简单说,网页爬虫就是按照一定的规则,自动抓取某一类网络信息的程序。

       比如,有些商家希望通过大量发送广告邮件的方式来推广自己的产品或服务。那么早期,商家就会编写一些程序,通过穷举的方法自动生成大量的邮件地址,然后自动向这些地址发送广告邮件。但是这种方法虽然能够生成大量的邮箱地址,但是其中有效的邮箱地址可能非常少,也就是说,其中可能包含大量还未被注册的邮箱地址。

       为了能够获取到更多的有效邮箱地址,人们便利用网页爬虫,从网页中获取邮箱地址。比如,某些论坛中,会有很多楼主开贴分享一些资源,有兴趣的网友就会将自己的邮箱留下来,希望楼主可以给自己发一份。那么就可以令网页爬虫从这一论坛页面中获取到这些网友的邮箱地址,大大提高了获取有效邮箱地址的效率。那么定义的规则其实就是需求3中匹配邮箱地址的正则表达式。

       当然,除了可以获取邮箱地址以外,还可以获取其他信息,比如搜索引擎等。搜索引擎的的基本原理也是网络爬虫,只不过是实现方式更为复杂和多样。

       我们这里仅仅是对网页爬虫的模拟过程,获取指定文本文件中的邮箱地址。由于要涉及到正则表达式的获取功能,因此要使用Pattern和Matcher类的实例对象。

思路:

       首先通过字符读取流读取包含有邮箱地址的文本文件。然后定义邮箱地址正则表达式,并将正则表达式封装为Pattern对象。每读取一行文本,则通过Pattern对象的matcher方法生成一个匹配引擎对象。通过这一引擎,结合find和group方法,获取到每一行文本中符合规则邮箱地址。

代码4:

public static void mailSpider1() throwsIOException {
	BufferedReader bufr = new BufferedReader(new FileReader("E:\\ mail.txt"));
 
	String mailRegex = "[a-zA-Z0-9_]+@[a-zA-Z-9]+(\\.[a-zA-Z]+){1,2}";
	Pattern pat = Pattern.compile(mailRegex);
	Matcher mat;
             
	String line = null;
	while((line = bufr.readLine()) != null){
		mat = pat.matcher(line);//生成每一行文本的匹配引擎
		while(mat.find()){
			System.out.println(mat.group());
		}
	}

	bufr.close();
}
执行结果为:

abc0@sina.com

abc1@sina.com

abc2@sina.com

abc3@sina.com

ab4c@sina.com

abc5@sina.com

abc6@sina.com

abc7@sina.com

abc8@sina.com

abc11@sina.com

abc9@sina.com

abc12@sina.com

abc55@sina.com

abc123@sina.com

abc1234@sina.com

qqq@sina.com

 

需求5:制作能够获取网页信息的网络爬虫,因此要涉及到前面所介绍的网络编程的内容。

思路:

       首先将需求4中的文本文本转换为一个“.html”文件,并保存在Tomcat服务器安装根目录下的webapps\mywebs文件夹中。

       然后将这一网页的URL封装为一个URL对象,并通过openConnection方法获取到与这一URL之间的通信链接对象——URLConnection对象。通过这一对象读取指定URL中的内容。同样,每读取一行文本,就生成这一行内容的匹配引擎,然后结合find和group方法获取到这一行文本中包含的邮箱地址。

代码5:

public static void mailSpider2() throwsIOException{
	URL url = new URL("http://localhost:8080/mywebs/mail.html");
 
	URLConnection conn = url.openConnection();
	InputStream receive = conn.getInputStream();
 
	String mailRegex = "[a-zA-Z0-9_]+@[a-zA-Z-9]+(\\.[a-zA-Z]+){1,2}";
	Pattern pat = Pattern.compile(mailRegex);
	Matcher mat;
             
	byte[] buf = new byte[1024];
	int len = 0;
	String line;
	while((len = receive.read(buf)) != -1){
		line = new String(buf, 0, len);
		mat = pat.matcher(line);
		while(mat.find()){
			System.out.println(mat.group());
		}
	}
 
	receive.close();
}
执行结果为:

abc0@sina.com

abc1@sina.com

abc2@sina.com

abc3@sina.com

ab4c@sina.com

abc5@sina.com

abc6@sina.com

abc7@sina.com

abc8@sina.com

abc11@sina.com

abc9@sina.com

abc12@sina.com

abc55@sina.com

abc123@sina.com

abc1234@sina.com

qqq@sina.com

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值