JavaSE实战——正则表达式、网页爬虫简述

转载请声明出处:http://blog.csdn.net/zhongkelee/article/details/47708405

简述

    正则表达式,字面意思就是正确的规则,它是专门用于操作字符串的规则。

    好处:规则是由符号组成的。正则的出现,使字符串的复杂操作变得更为简单。

    特点:将对字符串操作的代码用一些符号来表示。只要使用了指定符号,就可以调用底层的代码对字符串进行操作。符号的出现,简化了代码的书写。

    弊端:符号的出现虽然简化了书写,但是却降低了阅读性。

    其实更多是用正则解决字符串操作的问题。所以学习正则其实就是学习符号的使用。

    示例:练习校验QQ号的传统方式和正则表达式方式。

package ustc.lichunchun.regex;

public class RegexDemo {

	public static void main(String[] args) {
		
		/*
		 * 正则表达式:正确的规则。专门用于对字符串的操作。
		 * 好处:规则是由符号组成的。正则的出现,使字符串的复杂操作变得更为简单。
		 * 特点:将对字符串操作的代码用一些符号来表示。只要使用了指定符号,就可以调用底层的代码对字符串进行操作。
		 * 符号的出现,简化了代码的书写。
		 * 弊端:符号的出现虽然简化了书写,但是却降低了阅读性。
		 * 其实更多是用正则解决字符串操作的问题。
		 * 所以学习正则其实就是学习符号的使用。
		 */
		String QQ = "0124763";
		boolean b = checkQQ(QQ);
		if(b){
			System.out.println(QQ+" is ok");
		}else{
			System.out.println(QQ+" is nonono");
		}
		System.out.println("-------------------");
		boolean b1 = QQ.matches("[1-9][0-9]{4,14}");
		System.out.println(QQ+": "+b1);
		System.out.println("-------------------");
		String temp = "aaaaa2";
		boolean res = temp.matches("a{5}\\d");
		System.out.println(temp+":"+res);
	}
	/*
	 * 校验QQ号。5~15位 只能是数字,0不能开头。
	 */
	public static boolean checkQQ(String QQ){
		boolean flag = false;
		int len = QQ.length();
		if(len>=5 && len<=15){
			if(!QQ.startsWith("0")){//或者charAt()
				try{
					long qq_num = Long.parseLong(QQ);
					flag = true;
					System.out.println("QQ:"+qq_num);
				}catch(NumberFormatException e){
					System.out.println("非法QQ号");
				}
			}else{
				System.out.println("不能0开头");
			}
		}else{
			System.out.println("长度错误");
		}
		return flag;
	}
}
常见操作

    下面重点介绍一下正则表达式对字符串的常见操作。具体可以分为匹配、分割、替换、获取这四大操作。这其中,前三个操作都是用的是java.lang.String类的成员方法,即match、split、replaceAll方法,但它们底层都是用正则对象实现的。

1.匹配

    String类中提供了匹配 boolean matches(regex) 的方法。

    String reg = "[1—9][0—9]{4,14}";
    boolean b = qq.matches(reg); //将正则和字符串关联对字符串进行匹配。

2.切割

    String类中提供了 String[] split(regex) 的方法。

3.替换

    String类中提供了String replaceAll(regex, replacement)的方法。

4.获取

    最后一个获取功能,String类没有给我们提供相应的方法,这里我们需要借助于另外两个对象:

    正则模式对象:java.util.regex.Pattern --> 封装正则
    匹配器对象:java.util.regex.Matcher --> 关联字符串

    具体来说:

    (1)先要将正则表达式编译成正则对象。使用的是Pattern中静态方法 compile(regex);
    (2)通过Pattern对象获取Matcher对象。Pattern用于描述正则表达式,可以对正则表达式进行解析。
         而将规则操作字符串,需要从新封装到匹配器对象Matcher中。
         然后使用Matcher对象的方法来操作字符串。如何获取匹配器对象呢?
         通过Pattern对象中的matcher方法。该方法可以正则规则和字符串想关联。并返回匹配器对象。
    (3)使用Matcher对象中的方法即可对字符串进行各种正则操作。

package ustc.lichunchun.regex;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexTest {

	public static void main(String[] args) {
		/*
		 * 演示正则表达式对字符串的常见操作。
		 * 
		 * String类中的match、split、replaceAll方法,底层都是用正则对象实现的。
		 * 
		 * 1.匹配
		 * 	String类中提供了匹配boolean matches(regex)的方法。
		 * 
		 * 2.切割
		 * 	String类中提供了String[] split(regex)的方法。
		 * 
		 * 3.替换
		 * 	String类中提供了String replaceAll(regex, replacement)的方法。
		 * 
		 * 4.获取
		 *  正则模式对象:java.util.regex.Pattern-->封装正则
		 *  匹配器对象:java.util.regex.Matcher-->关联字符串
		 */

		//matchesDemo();//匹配
		//splitDemo();//分割
		//replaceDemo();//替换
		getDemo();//获取
	}

	public static void matchesDemo() {
		//需求:校验手机号码是否正确。
		String tel = "15855159331";
		String regex = "1[358]\\d{9}";
		boolean b = tel.matches(regex);
		System.out.println(tel+":"+b);
	}

	public static void splitDemo() {
		String temp = "zhangsan    lisi       wangwu";
		String regex = " +";
		
		String temp1 = "zhangsan.lisi.wangwu";
		String regex1 = "\\.";//正则会将'.'解析为特定含义,代表任意字符,
		//但是我们这里需要的就是'.'特定字符,所以用转义字符'\.'和转义字符'\\'。
		
		String temp2 = "qwe##rty$$$$tyuvvvvvvvio";
		String regex2 = "(.)\\1+";//为了实现规则的复用,用()将需要复用的规则封装,
								//就称为正则表达式中的"组",每一个组都有一个编号,从1开始。(组零始终代表整个表达式)
								//通过使用编号就可以复用对应组的规则内容。(编号也必须使用\\转义)
								//注意:编号必须用在组的后面。也就是说:先封装完规则再用角标调用。
		
		//   ((A)(B(C)))  共四组,有几个左括号,就有几组。最左边的左括号封装的是第1组,以此类推。			
		
		String[] names = temp2.split(regex2);
		for (String name : names) {
			System.out.println("-"+name+"-");
		}
	}
	
	public static void replaceDemo() {
		String temp = "15855159331";
		temp = temp.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
		//在一个字符串规则中,用'\编号'的形式就可以取组了。
		//$可以在多参数时,后面的参数可以通过'$编号'的形式取到前一个参数的组。
		
		String temp1 = "qwe##rty$$$$tyuvvvvvvvio";
		temp1 = temp1.replaceAll("(.)\\1+", "$1");
		
		System.out.println(temp1);
	}

	public static void getDemo() {
		/*
		 * 实现获取:将符合规则的内容取出来,用到正则表达式对象。java.utilregex.Pattern
		 * 
		 * 思路:
		 * 1.将字符串规则封装成Pattern对象。Pattern compile(regex);
		 * 2.通过正则模式对象Pattern获取匹配器对象Matcher。用于将正则规则作用到要操作的字符串上。Matcher matcher(input);
		 * 3.通过匹配器对象的方法,对字符串进行操作。
		 * 
		 * Pattern p = Pattern.compile("a*b");//将规则编译成对象。
		 * Matcher m = p.matcher("aaaaab");//和要操作的字符串关联,生成匹配器对象。
		 * boolean b = m.matches();//使用匹配器对象的方法对字符串进行操作。
		 */
		
		//需求:获取字符串中符合规则的内容。
		String temp = "da jia zhu yi le,ming tina fang jia le!";
		System.out.println(temp);
		
		//取出由三个字母组成的单词,注意单词边界。
		String regex = "\\b[a-zA-Z]{3}\\b";
		
		//1.将规则编译成Pattern对象。
		Pattern p = Pattern.compile(regex);
		
		//2.和字符串关联,获取匹配器对象。
		Matcher m = p.matcher(temp);
		
		while(m.find()){
			System.out.println(m.start()+":"+m.group()+":"+m.end());//根据start和end,getSubString.
		}
		
		/*
		da jia zhu yi le,ming tina fag jia le!
		3:jia:6
		7:zhu:10
		32:jia:35
		*/
	}
}
练习1:将"我我....我我我....我要....要...要要....要要..学学学...学学编...编编..编编程程....程..程程" 还原成:我要学编程。

练习2:对ip地址进行排序:"192.168.1.200    17.10.10.10  3.3.50.3   127.0.0.1"。

练习3:校验邮件地址。

package ustc.lichunchun.regex;

import java.util.Arrays;

public class YourRegexTest {

	public static void main(String[] args) {
		//test_1();
		//test_2();
		checkMail();
	}

	/* 
	 * 练习1:
	 * "我我....我我我....我要....要...要要....要要..学学学...学学编...编编..编编程程....程..程程"
	 * 还原成:我要学编程。
	 */
	public static void test_1() {
		
		String temp = "我我....我我我....我要....要...要要....要要..学学学...学学编...编编..编编程程....程..程程";
		
		//1.明确要使用替换。replaceAll(regex, String)
		
		//2.将点先干掉
		temp = temp.replaceAll("\\.+", "");
		
		//3.将叠词干掉
		temp = temp.replaceAll("(.)\\1+", "$1");
		System.out.println(temp);
	}
	
	/*
	 * 练习2:对ip地址进行排序。
	 * 192.168.1.200    17.10.10.10	   3.3.50.3	   127.0.0.1
	 */
	public static void test_2(){
		String temp = "192.168.1.200    17.10.10.10	   3.3.50.3	  127.0.0.1";
		//String[] ips = temp.split(" +");
		//Arrays.sort(ips);//这是按照字符串字典顺序排的,不符合需求。
		
		/*
		问题在哪儿呢?是因为每一个地址段的位数不对。
		如果位数都是三位就可以了。只有补0了。
		每一段位数都不同,咋补?
		干脆按照最大所需0的个数补齐。每一段都补两个0。但最终我们只截取每段的最后三位。
		*/
		//补两个0,连续数字。
		temp = temp.replaceAll("(\\d+)", "00$1");
		
		//保留每段最后3位
		temp = temp.replaceAll("0*(\\d{3})", "$1");
		
		//排序
		String[] ips = temp.split(" +");
		Arrays.sort(ips);
		//或者:
		//TreeSet<String> ts = new TreeSet<String>();
		//ts.add(ip);
		
		for(String ip : ips){
			System.out.println(ip.replaceAll("0*(\\d+)", "$1"));
		}
	}

	/*
	 * 练习3:校验邮件地址。
	 */
	public static void checkMail(){
		String mail = "abc12@sina.com.cn";
		
		String regex = "\\w+@[a-zA-Z0-9]+(\\.[a-zA-Z]{2,3}){1,3}";
		regex = "\\w+@\\w+(\\.\\w+)+";//笼统方式,1@1.1都行。
		
		boolean b = mail.matches(regex);
		
		System.out.println(mail+":"+b);
	}
}

练习4:去除一串数字中连续相同的3个数字,如1122333224455546667,变成1127。(华为2016机试题

package huawei.job;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main33 {

	public static void main(String[] args) {
		String line = "1122333224455546667";
		while(isRepeatNum(line)){
			line = line.replaceAll("(\\d)\\1{2}", "");
		}
		System.out.println(line);
	}
	public static boolean isRepeatNum(String str){
		Matcher m = Pattern.compile("(\\d)\\1{2}").matcher(str);
		//-- \\d已经算一个数字,后面\\1{2}是接着这个数字后的相同两个数字
		if(m.find()){
			return true;
		}
		return false;
	}
}

爬虫

    网络爬虫:其实就是一个程序用于在互联网中获取符合制定规则的数据。

    示例:爬取文件中的邮箱地址。

package ustc.lichunchun.netspider;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class NetSpider {

	public static void main(String[] args) throws IOException {
		/*
		 * 网络爬虫:其实就是一个程序用于在互联网中获取符合制定规则的数据。
		 * 
		 * 爬取邮箱地址。
		 */
		
		//1.将文件封装成File对象。
		File file = new File("mail.htm");
		String regex = "\\w+@\\w+(\\.\\w+)+";
		List<String> mailList = getMails(file, regex);
		for(String mail:mailList){
			System.out.println(mail);
		}
	}

	public static List<String> getMails(File file, String regex) throws IOException {
		//1.读取数据。
		BufferedReader bufr = new BufferedReader(new FileReader(file));
		//2.将正则封装成对象。
		Pattern p = Pattern.compile(regex);
		//3.定义List集合。
		List<String> list = new ArrayList<String>();
		String line = null;
		while((line = bufr.readLine())!=null){
			//4.对读取的数据进行规则的匹配,从中获取符合规则的数据。
			Matcher m = p.matcher(line);
			while(m.find()){
				//5.将符合规则的数据存储到集合中。
				list.add(m.group());
			}
		}
		return list;
	}
}
    练习:网页爬虫。(其实就是利用网络通信和URL技术,后一篇博客会详细介绍JavaSE网络编程)

    参考代码后续会补上~~~微笑

    转载请声明出处:http://blog.csdn.net/zhongkelee/article/details/47708405

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值