黑马程序员——正则表达式

------- android培训java培训、期待与您交流! ----------

什么是正则表达式?

正则表达式: 符合一定规则的表达式

作用:用于专门操作字符串
特点:用一些特定的符号来表示一些代码操作,这样就简化书写。
所以学习正则表达式,就是在学习一些特殊符号的使用

好处: 可以简化字符串的复杂操作
弊端: 符号定义越多,正则越长,阅读性越差。

正则表达式的规则










具体操作功能

1,匹配:String matches()。用规则匹配整个字符串,只要有一处不符合规则,就匹配结束,返回false。
如:[a-zA-z]\\d*匹配b35可以匹配,但是匹配b35a就不可以匹配。因为一开始匹配b时,匹配成功,匹配35时匹配不成功,再匹配a时,就匹配不成功。
   只要有一处不符合规则,则匹配不成功

2,替换String replaceAll()

3,切割:String split(); (拿到规则以外的子串)  如:字符串是"abckkdefkkqwekk",如果规则是"kk",那么获取到的结果是abc,def,qwe

4,获取:
将字符串中符合规则的字串取出 (拿到符合规则的子串)
 
  操作步骤:
  1,将正则表达式封装成对象
  2,让正则对象和要操作的字符串相关联
  3,关联后,获取正则匹配引擎
  4,通过引擎,对符合规则的字串进行操作,比如取出


以上四种功能中,使用哪一个呢?
思路方式:


1,如果只想知道字符串是对是错,用匹配。
2,如果想将已有的字符串变成另一个字符串,用替换
3,如果按照指定的方式将字符串变成多个字符串,用切割。切割是获取规则以外的字串
4,如果想要拿到符合需求的字符串字串,用获取。获取时拿到符合规则的字串

匹配:String matches方法。

/*

 匹配:String matches方法。

 需求:
 	 对qq号进行校验 要求:1~15 0不能开头,只能是数字

 */
public class Demo {
	public static void main(String[] args) throws Exception {
		// function_1();
		function_2();
	}

	//使用正则表达式
	public static void function_2() {
		String qq = "1233456666";

		String regex = "[1-9][0-9]{4,14}";//规则是:第一位是1-9之间的数字。第二位是0-9之间,并且长度为4-14

		boolean flag = qq.matches(regex);
		if (flag)
			System.out.println(qq + "正确");
		else
			System.out.println(qq + "格式错误");

	}

	//这种方式,使用了String类中的方法,进行组合完成了需求,但是代码过于复杂
	public static void function_1() {
		String qq = "1233456666";
		if (!(qq.length() >= 5 && qq.length() <= 15)) {
			System.out.println("长度必须 5 <= x <= 15");
			return;
		}

		if (qq.charAt(0) == '0') {
			System.out.println("首字母不能为0");
			return;
		}

		// char chs[] = str.toCharArray();
		// for (int i = 0; i < chs.length; i++) {
		// if (!(chs[i] >= '0' && chs[i] <= '9')) {
		// System.out.println("输入的不是数字");
		// return;
		// }
		// }

		try {
			long l = Long.parseLong(qq);//不能使用Integer.parseInteger(qq)。因为qq的长度有可能超过int类型
		} catch (Exception e) {
			System.out.println("输入的不是数字");
			return;
		}

		System.out.println("正确");

	}
}

切割:String split()

/*
  切割:String split();
	
 */
public class Demo {
	public static void main(String[] args) throws Exception {
		//splitDemo("abc def ghi", " ");//切割空格
		//splitDemo("abc  def    ghi", " +");//切割一个或多个空格," +"代表一个或多个空格
		
		//splitDemo("abc.def.ghi","\\.");//切割.	,因为.在正则表达式中代表任何字符,所以\.在正则表达式中代表.	,而转换到java中时需要\\.
		//splitDemo("C:\\abc\\a.txt","\\\\");// 切割\\	,在正则表达式中\\代表一个\,所以切割\\,需要使用\\\\
		
		//splitDemo("abckkdefkkhikkg", "kk");//切割叠词 kk

		//splitDemo("abcddefgghijj", "(.)\\1");//切割叠词dd,gg,gg。	为了可以让规则的结果被重用,可以将规则封装成一个数组。
									//用()完成。组的出现都有编号,从1开始。想要使用已有的组,可以通过 \n (n就是组的编号)的形式获取
									//在此例中, .代表任意字符,将.放在一个组中(.),  (.)\\1   代表重用第1个组。
									//既:如果.是一个字符k,那么(.)\\1,就代表重用第一个组中的k,那么(.)\\1相当于kk
									//有多少个组,看左括号 "(" 的个数。
									//如:((A)(B(C))) 代表4个组。第一个组是((A)(B(C))) 二组是(A)  三组(B(C))   四组(C)


		//想按照出现一对对的字符进行切割。例如,对ee进行切割,想获取到的结果为abe,esa,d。
		//splitDemo("abeeesaeeeed","(ee)+");//  (ee)代表对字符串ee,并封装进一个组中。(ee)+ 代表ee这个字符串出现一次或者多次都符合规则

		
		//想按照出现一对对的字符进行切割。如:对ee和qq切割,想获取到的结果为abc,esa,d
		//splitDemo("abeeesaqqqqd","((.)\\2)+");//此规则中有两个括号,里边的(.)代表任意字符,并存放在一个组中。(.)\\2代表重用括号里面的内容,
						//如果括号中的.为e,那么(.)\\2代表ee。为什么此规则写的是(.)\\2而不是(.)\\1呢?
						//因为,在整个规则中,是按左括号"("的个数来确定是第几组数的,在此规则中,因为(.)的左括号是整个规则中的第2个左括号,
						//所以(.)是在第2组,所以(.)\\2代表重用的就是(.),那么(.)\\1代表重用的就是第一个左括号中的内容,既重用((.)\\2)

		
		splitDemo("abcddddefgggggghijj", "(.)\\1+");//.这个任意字符是一个组,\\1是重用第一个组,+代表出现了1次或多次
		
	}
	
	//对特定的字符串进行切割
	public static void splitDemo(String str,String regex) {
		String[] ss = str.split(regex);
		for(String s : ss){
			System.out.println(s);
		}
	}
}

替换:String replaceAll()

/*
 替换:String replaceAll();
 */
public class Demo {
	public static void main(String[] args) throws Exception {
		
		String str = "wef342523asfasdf563456ljlj6757asdf352435";//将字符串中出现至少5次的数字换成#
		replaceAllDemo(str,"\\d{5,}","#");//wef#asfasdf#ljlj6757asdf#
		
		String str1 = "abcddeffffghiiijkaakqq";//将字符串中的叠词替换成&
		replaceAllDemo(str1,"(.)\\1+","&");//abc&e&gh&jk&k&		()代表组,.代表任意字符,\\1代表获取组中内容,
							//如果.的字符是k,那么(.)代表将k视为一个组,\\1代表获取第一组中的内容,+代表出现1次或者多次,
							//所以,(.)\\1+ 代表获取第一组中的字符,并且出现1次或者多次。
							//如:(.)如果为k,那么(.)\\1代表kk,(.)\\1+ 代表kk出现1次或者多次
		
		String str2 = "abcddeffffghiiijkaakqq";//将重叠的字符换成单个字符。kkkk --> k
		replaceAllDemo(str2, "(.)\\1+", "$1");//abcdefghijkakq		$1也代表获取第一组中的内容,$1与\\1不同,\\1是正则表达式中获取第一组,
							// $1代表可以在正则表达式外获取第一组
		
	}
	
	//使用给定的 newStr 替换此字符串所有匹配给定的正则表达式的子字符串。
	public static void replaceAllDemo(String str,String regex,String newStr) {
		
		str = str.replaceAll(regex, newStr);
		System.out.println(str);
	}
}

获取:将字符串中符合规则的字串取出

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

/*
 获取:将字符串中符合规则的字串取出
 
 操作步骤:
 	1,将正则表达式封装成对象
 	2,让正则对象和要操作的字符串相关联
 	3,关联后,获取正则匹配引擎
 	4,通过引擎,对符合规则的字串进行操作,比如取出
 */
public class Demo {
	public static void main(String[] args) throws Exception {
		getDemo();
		
	}
	
	public static void getDemo(){
		String str = "ming tian yao fang jia le";
		
		String regex = "\\b[a-z]{3}\\b";//英文字符连续出现3次的都符合规则,\\b代表单词边界。
						//如果将边界\\b去掉,那么结果为min,tia,yao,fan,jia,因为一开始时,前3个单词就已经符合规则了
		
		//将规则封装成对象
		Pattern p = Pattern.compile(regex);
		
		//让正则表达式和要作用的字符串相关联,并返回一个匹配器引擎
		Matcher m = p.matcher(str);
		
		//System.out.println(m.matches());//false		其实String类中的matches方法。用的就是Pattern和Matcher对象来完成的。
					//只不过被String的方法封装后,用起来比较简单,但是功能比较单一
		
		//boolean b = m.find();//将规则作用到字符串上,并进行符合规则的字串查找。
		//System.out.println(b);//true
		//System.out.println(m.group());//yao		用于获取匹配后的结果,但是只获取到一次就无法获取了,所以需要使用循环去获取
		
		while(m.find()){//将规则作用到字符串上,并进行符合规则的字串查找
			System.out.println(m.group());// yao	jia	用于获取匹配后的结果,但是只获取到一次就无法获取了,所以需要使用循环去获取
		}
	}
}

练习

/*

 练习:
 	 匹配手机号码
 	 13XXX	15XXX	18XXX
 */
public class Demo {
	public static void main(String[] args) throws Exception {
		
		function("13807569135");
	}

	public static void function(String str) {
		String regex = "1[358]\\d{9}";//第一位是1,第二位3或5或8,后边9位是0-9之间的数字
		
		boolean flag = str.matches(regex);
		System.out.println(flag);
	}
}
<pre name="code" class="java">/*
 练习:
 将下列字符串转成:我要编程	
 "我我...我我...我要...要...要要...学学学....学学...编编编...编程..程.程程...程...程"
 */
import java.util.Arrays;
import java.util.regex.*;

public class Demo {
	public static void main(String[] args) throws Exception {
		String str = "我我...我我...我要...要...要要...学学学....学学...编编编...编程..程.程程...程...程";
		
		
		/*
		 将已有字符串变成一个字符串。使用  替换功能
		 思路:
		 	1,可以先将 . 去掉
		 	2,再将多个重复的内容变成单个内容
		 */
		
		str = str.replaceAll("\\.", "");//将 . 去掉
		System.out.println(str);//我我我我我要要要要学学学学学编编编编程程程程程程
		str = str.replaceAll("(.)\\1+", "$1");//将重复的内容变成单个内容
		System.out.println(str);//我要学编程
	}
}


 
 
/*
 练习:
 	将一下ip地址进行地址段顺序的排序
 	
 	"192.168.1.254    102.49.23.13  10.10.10.10   2.2.2.2   8.109.90.30"
 	
 	排序后的结果为
 	2.2.2.2
 	8.109.90.30
 	10.10.10.10
 	102.49.23.13
 	192.168.1.254
 */
import java.util.Arrays;
import java.util.TreeSet;
import java.util.regex.*;

public class Demo {
	public static void main(String[] args) throws Exception {
		ipSort("192.168.1.254    102.49.23.13  10.10.10.10   2.2.2.2   8.109.90.30");
	}
	
	/*
	 思路:
	 	需要按照字符串的自然顺序排序,只要让他们每一段都是3位即可
	 	1,按照每一段需要的最多的0进行补齐,那么每一段就会至少保证有3位
	 	2,将多余的0删除,使得每一段ip地址只保留3位
	 	3,将ip地址进行排序
	 	4,在ip地址中,将前边的0删除
	 */
	public static void ipSort(String ip){
		ip = ip.replaceAll("(\\d+)", "00$1");//在每一个数字的前面补两个0
		System.out.println(ip);//00192.00168.001.00254    00102.0049.0023.0013  0010.0010.0010.0010   002.002.002.002   008.00109.0090.0030
		
		ip = ip.replaceAll("0*(\\d{3})", "$1");//为了保证都是三位数,将多余的0删除
		System.out.println(ip);//192.168.001.254    102.049.023.013  010.010.010.010   002.002.002.002   008.109.090.030
		
		String[] ips = ip.split(" +");//将一个到多个空格删除
		
		TreeSet<String> ts = new TreeSet<String>();
		for(String s : ips)
			ts.add(s);
		for(String s : ts){
			System.out.println(s.replaceAll("0*(\\d+)","$1"));//将多余的0删除
			/*
			 	2.2.2.2
				8.109.90.30
				10.10.10.10
				102.49.23.13
				192.168.1.254
			 */
		}
		
	}
}


/*
 练习:
 	对邮件地址进行校验
 */
import java.util.Arrays;
import java.util.TreeSet;
import java.util.regex.*;

public class Demo {
	public static void main(String[] args) throws Exception {
		checkMail("982abb@qq.com");//true
		checkMail("982abb@qq.com.cn");//true
		checkMail("982abb@qq_.com_.cn");//false

		//   \\w{5,12}@\\w+(\\.[a-zA-Z]+)+
	}
	
	public static void checkMail(String mail){//检查邮件
		System.out.println(mail.matches("\\w{6,12}@\\w+(\\.[a-zA-Z]+)+"));
		/*
		 	\\w代表出现的字符包括大小写字母和下划线_。\\w{6,12}代表大小写字母或者下划线出现的次数为6~12次。
		 	\\w{6,12}@代表出现6~12此大小写字母后出现@字符。\\w+ 代表大小写字母或者下划线_出现的次数为1次或者1次以上。
		 	\\.代表出现一个点. 。[a-zA-Z]+代表大小写字母出现一次或者多次。(\\.[a-zA-Z]+)+ 代表 .和[a-zA-Z]+出现一次或者一次以上
		 */
		
	}
}


网页爬虫

/*
 模拟网页爬虫(蜘蛛)
 获取一个文件中的邮箱
 */
import java.io.*;
import java.net.*;
import java.util.regex.*;

public class Demo {
	public static void main(String[] args) throws Exception {
		method2();
	}

	public static void method2() throws Exception {
		URL url = new URL("file:///C:/Users/user/Desktop/web.html");
		URLConnection conn = url.openConnection();

		BufferedReader bufr = new BufferedReader(new InputStreamReader(
				conn.getInputStream()));

		String regex = "\\w+@\\w+(\\.\\w+)+";
		Pattern p = Pattern.compile(regex); // 将规则封装成对象

		String line = null;
		while ((line = bufr.readLine()) != null) {
			Matcher m = p.matcher(line);// 将正则表达式和字符串相关联,并返回一个匹配器引擎
			while (m.find())
				System.out.println(m.group());
		}
	}

	public static void method1() throws Exception {
		BufferedReader bufr = new BufferedReader(new FileReader("C:\\mail.txt"));
		String regex = "\\w+@\\w+(\\.\\w+)+";
		Pattern p = Pattern.compile(regex); // 将规则封装成对象

		String line = null;
		while ((line = bufr.readLine()) != null) {
			Matcher m = p.matcher(line);// 将正则表达式和字符串相关联,并返回一个匹配器引擎
			while (m.find())
				System.out.println(m.group());
		}
	}
}
















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值