java学习笔记——正则表达式

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

  • 用途:用于专门操作字符串的规则
  • 优点:可以简化对字符串的复杂操作
  • 缺点:符号定义越多,正则表达式越长,阅读性越差

语法规则:
Regular_expression

示例

package regular_expression;
/**
 * 正则表达式:符合一定规则的表达式
 * 用途:用于专门操作字符串的规则
 * 优点:可以简化对字符串的复杂操作
 * 缺点:符号定义越多,正则表达式越长,阅读性越差
 * @author MCC
 * 需求:对QQ号码进行校验,要求:5-15位,0不能开头,只能是数字
 */
public class RegularExpression {
	public static void main(String[] args) {
//		System.out.println(check("1425146201"));
//		System.out.println(myCheck("1425146201"));	
		System.out.println(regularCheck("1425146201"));
	}
	public static boolean check(String str) {
		int count = str.length();
		boolean flag1 = false, flag2 = true, temp = false;
		if((count>=5&&count<=15) && !str.startsWith("0")) {
			flag1 = true;
		}
		for(int i=0; i<str.length(); i++) {
			temp = str.charAt(i)<='9' && str.charAt(i)>='0';
			flag2 = temp && flag2;
			//或者转换成数组
//			char[] ch = str.toCharArray();
//			for(int i=0; i<ch.length; i++){}
		}
		return flag1 && flag2;
	}
	/*
	 * 一种简单写法
	 */
	public static boolean myCheck(String str) {
		if(!str.startsWith("0")) {
			if(str.length()>=5 && str.length()<=15) {
				//改进之处
				try {
					long l = Long.parseLong(str);//如果包含字母,则转换失败,报异常
					return true;
				}catch(NumberFormatException e) {
					System.out.println("只能是纯数字");
				}
			}else {
				System.out.println("长度应为0-15之间");
			}
		}else {
			System.out.println("不能用0开头");
		}
		return false;
	}
	/*
	 * 使用正则表达式
	 */
	public static boolean regularCheck(String str) {
		//使用boolean matches(String regex)//String regex是正则表达式
		String reg = "[1-9][0-9] {4,14}";
		boolean flag = str.matches(reg);
		return flag;
	}
}

匹配

package regular_expression;
/**
 * 正则表达式:匹配
 * boolean matches(String regex)//用规则匹配整个字符串,只要有一处不符合规则,就匹配结束,返回false.
 * 
 * @author MCC
 * 
 * 字符类:
 * [abc]	判断字符串上某一位置出现的字符是否为abc之一
 * [^abc]	Any character except a, b, or c (negation) 否定
 * [a-zA-Z]	a through z or A through Z, inclusive (range) 范围
 * [a-d[m-p]]	a through d, or m through p: [a-dm-p] (union) 并集
 * [a-z&&[def]]	d, e, or f (intersection) 交集
 * [a-z&&[^bc]]	a through z, except for b and c: [ad-z] (subtraction) 减去
 * [a-z&&[^m-p]]	a through z, and not m through p: [a-lq-z](subtraction) 减去
 * 
 * 预定义字符类:要使用\\d, \\D, 因为\是转义字符
 * .	Any character (may or may not match line terminators)
 * \d	A digit: [0-9]
 * \D	A non-digit: [^0-9]
 * \h	A horizontal whitespace character: [ \t\xA0\u1680\u180e\u2000-\u200a\u202f\u205f\u3000]
 * \H	A non-horizontal whitespace character: [^\h]
 * \s	A whitespace character: [ \t\n\x0B\f\r]
 * \S	A non-whitespace character: [^\s]
 * \v	A vertical whitespace character: [\n\x0B\f\r\x85\u2028\u2029]
 * \V	A non-vertical whitespace character: [^\v]
 * \w	A word character: [a-zA-Z_0-9]
 * \W	A non-word character: [^\w]
 * 
 * Greedy 数量词:
 * X?	X, once or not at all
 * X*	X, zero or more times
 * X+	X, one or more times
 * X{n}	X, exactly n times
 * X{n,}	X, at least n times
 * X{n,m}	X, at least n but not more than m times
 * 
 */
public class RegularMatch {
	public static void main(String[] args) {
		String str = "a";
		String reg = "[bc]";//字符串第一个位置只能是bc中的一个,并且字符串只能有一个字符
							//如果去掉[]代表第一位只能是b,第二位只能是c
		boolean flag = str.matches(reg);
		System.out.println(flag);//false 
		
		System.out.println(checkTel("13464623061"));
	}
	//匹配电话号码
	public static boolean checkTel(String num) {
		/*
		 * 假设手机号段只有13X, 15X, 18X
		 */
		String reg = "[1][358]\\d{9}";
		return num.matches(reg);
	}
}

切割

package regular_expression;
/**
 * 切割:
 * String[] split(String regex)
 * @author MCC
 *
 */
public class RegularSplit {
	public static void main(String[] args) {
		mySplit("www.baidu.com", "\\.");//以.切割
		mySplit("C:\\Users\\MCC\\Desktop", "\\\\");//以\\切割(转义字符)
		mySplit("abcddeffgh", "(.)\\1");
		/* 以叠词切割, 
		 * ()是组的概念, (.)代表第一组上的数任意取值, 
		 * \1代表第二位上的数要与第一组中的数相同, 由于 \ 是转义字符, 因此想表达 \ 要使用 \\
		 * 
		 * 组:
		 * 若想将某个规则作用后的结果被重用,可以将该规则封装成一个组,用()表示,
		 * 每个组都有自己的编号,从1开始,想要使用已有的组时,通过 \n 的形式完成(n是组的编号, 由于转义字符, 要使用 \\)
		 * 
		 * ((A)(B(C))) 有4组
		 * 1. ((A)(B(C)))
		 * 2. (A)
		 * 3. (B(C))
		 * 4. (C)
		 */
		mySplit("duwfka1xdowjf1xd1xd161258", "([1][x][d])\\1");//在出现1xd1xd的位置切割
		//在出现ac1xd1xd的位置切割
		mySplit("duwfkaac1xdowjfac1xd1xd161258", "([a][c]([1][x][d]))\\2");
	}
	public static void mySplit(String str, String regex) {
		String[] s = str.split(regex);
		for(String ss : s) {
			System.out.print(ss+"  ");
		}
		System.out.println();
	}
}

替换

package regular_expression;
/**
 * 替换:(String replace()//不使用正则表达式)
 * String replaceAll(String regex, String replacement)
 * @author MCC
 *
 */
public class RegularReplace {
	public static void main(String[] args) {
		String str = "1an8c341bci86csb22l100xke3yw722";
		String str1 = "12ee3566tt19982qq74wwww8qq";
		myReplaceAll(str, "\\d+", "#");//将字符串中的数字替换成#
		myReplaceAll(str, "\\d{2,}", "#");//将字符串中的数字连续出现2次或两次以上的替换为#
		myReplaceAll(str1, "(.)\\1+", "#");//将字符串中的叠词替换成#,qqqq变成#, 而非##
		myReplaceAll(str1, "(\\D)\\1+", "#");//将字符串中的字母叠词替换成#
		//将重叠的字母替换成单个字母
		//$n-替换操作中的特殊操作
		myReplaceAll(str1, "(\\D)\\1+", "$1");//$n-获取第n组中的元素,本例中,有叠词tt,则$1==t
		
		//将每个字符前加两个0
		String str2 = "abcdefg";
		myReplaceAll(str2, "(\\D)", "00$1");
	}
	public static void myReplaceAll(String str, String regex, String newStr) {
		String s = str.replaceAll(regex, newStr);
		System.out.println(s);
	}
}

获取

1. 步骤:

  1. 将正则表达式封装成对象——Pattern对象
  2. 让正则表达式对象与要操作的字符串相关联——compile()
  3. 关联后,获取正则匹配引擎——Matcher对象
  4. 通过引擎对符合规则的子串进行操作,比如取出——使用Matcher类提供的方法

2.

  • 正则表达式regular-expression属于Pattern类
  • Pattern类在Package java.util.regex下
  • Pattern类不能new对象,通过下述方法将正则表达式封装成Pattern对象
    static Pattern compile​(String regex)
    static Pattern compile​(String regex, int flags)

3.
两个方法:

  1. 将原字符串与规则进行匹配, 注意:只匹配一次
    boolean find()
    boolean find​(int start)
    从指定位置开始获取
  2. 获取匹配后的结果(取出满足规则的子串),注意:只取出一次
    String group()

4.

  • 获取与规则匹配的子串的开始位置和结束位置
    int start()
    int end()

    包含start,不包含end
package regular_expression;
/**
 * 获取:将字符串中符合规则的子串取出
 * 操作步骤:
 * 1.将正则表达式封装成对象
 * 2.让正则表达式对象与要操作的字符串相关联
 * 3.关联后,获取正则匹配引擎
 * 4.通过引擎对符合规则的子串进行操作,比如取出
 * @author MCC
 * 正则表达式regular-expression属于Pattern类
 * Pattern类在Package java.util.regex下
 * Pattern类不能new对象,通过下述方法将正则表达式封装成Pattern对象
 * static Pattern compile​(String regex)	
 * static Pattern compile​(String regex, int flags)	
 */

import java.util.regex.*;

public class RegularGet {
	public static void main(String[] args) {
		getString();
	}
	public static void getString() {
		String str = "ming tian jiu yao fang jia le";
		//将字符串中连续三个字母组成的子串取出
		//1.将正则表达式封装成对象
		String regex = "[a-z]{3}";
		String regex1 = "\\b[a-z]{3}\\b";//加入单词边界匹配器
		Pattern p = Pattern.compile(regex1);
		//2.让正则表达式对象与要操作的字符串相关联,并获取匹配器(引擎),即Matcher对象
		Matcher m = p.matcher(str);//matcher(CharSequence input), String是CharSequence的子类
		//Matcher类有许多方法,其中String类的matches(),replaceAll()
		//就是封装了Pattern类和Matcher类的方法实现的
		/*
		 * 两个方法:
		 * 1. 将原字符串与规则进行匹配, 注意:只匹配一次
		 * boolean	find()	
		 * boolean	find​(int start)//从指定位置开始获取
		 * 2.获取匹配后的结果(取出满足规则的子串),注意:只取出一次
		 * String	group()
		 */
		//循环获取所有符合规则的子串
		while(m.find()==true) {
			System.out.println(m.group());//匹配的结果有些不是单词,要找到单词的边界
			/*
			 * 获取与规则匹配的子串的开始位置和结束位置
			 * int	start()
			 * int	end()
			 * 包含start, 不包含end
			 */
			System.out.println(m.start()+"..."+m.end());
		}
		/*
		边界匹配器:
		^	The beginning of a line
		$	The end of a line
		\b	A word boundary
		\b{g}	A Unicode extended grapheme cluster boundary
		\B	A non-word boundary
		\A	The beginning of the input
		\G	The end of the previous match
		\Z	The end of the input but for the final terminator, if any
		\z	The end of the input
		*/
		
	}
}

练习

  • 判断字符串是否正确–匹配
  • 将已有的字符串变成另一个字符串–替换
  • 按照要求将已有字符串变成多个字符串–切割(获取规则以外的字符串)
  • 获取符合要求的字符串–获取(获取符合规则的字符串)

程序1

package regular_expression;
/**
 * 判断字符串是否正确--匹配
 * 将已有的字符串变成另一个字符串--替换
 * 按照要求将已有字符串变成多个字符串--切割(获取规则以外的字符串)
 * 获取符合要求的字符串--获取(获取符合规则的字符串)
 * @author MCC
 *
 */
public class RegularPractice1 {
	public static void main(String[] args) {
		//将下述字符串转换成:我是中国人
		String str = "我我...我..是是是..是是是...中中国..人.";
		/*
		 * 替换:
		 * 1.去掉.
		 * 2.将叠词变成单个字符
		 */
		str = str.replaceAll("\\.+", "");
		System.out.println(str);//我我我是是是是是是中中国人
		str = str.replaceAll("(.)\\1+", "$1");
		System.out.println(str);//我是中国人
	}
}

程序2

将ip地址按照地址段排序

package regular_expression;

import java.util.TreeSet;

/**
 * 将ip地址按照地址段排序
 * @author MCC
 *
 */
public class RegularPractice2 {
	public static void main(String[] args) {
		String ip = "192.168.0.154 102.49.23.13 10.10.10.10 8.109.90.30";
		//将ip拆成String[]在进行比较不行,因为192与8进行比较时,逐位进行比较,1<8,192排在了8的前面,错误
		//1.将每位补两个0
		ip = ip.replaceAll("(\\d+)", "00$1");
		//00192.00168.000.00154 00102.0049.0023.0013 0010.0010.0010.0010 008.00109.0090.0030
		//2.取前三位
		ip = ip.replaceAll("0*(\\d{3})", "$1");//0开头(可以不存在),数字一共出现3次
		//192.168.000.154 102.049.023.013 010.010.010.010 008.109.090.030
		//3.以空格为切割符切割
		String ip_str[] = ip.split(" ");
		//4.存入到TreeSet中,自动排序
		TreeSet<String> tr = new TreeSet<String>();
		for(String temp : ip_str) {
			tr.add(temp);
		}
		//打印数据
		for(String ip_res : tr) {
			//打印时不打印最前面的0
			System.out.println(ip_res.replaceAll("0+(\\d+)", "$1"));
			/*
			8.19.90.30
			10.10.10.10
			12.49.23.13
			192.168.0.154
			*/
		}
	}
}

程序3

对邮件地址进行校验

package regular_expression;
/**
 * 对邮件地址进行校验
 * @author MCC
 *
 */
public class RegularPractice3 {
	public static void main(String[] args) {
		System.out.println(checkMailAddress("1654882116@qq.com"));
		System.out.println(checkMailAddress("zhangsan123@xyz.edu.cn"));
	}
	public static boolean checkMailAddress(String address) {
		//可以验证123@abc.com类的邮箱
//		String regex = "\\w{5,15}@[a-zA-Z0-9]+\\.[a-zA-Z]+";
		//可以验证123@abc.com.cn类的邮箱
//		String regex = "\\w{5,15}@[a-zA-Z0-9]+\\.[a-zA-Z]+\\.[a-zA-Z]+";
		//综合结果
//		String regex = "\\w{5,15}@[a-zA-Z0-9]+(\\.[a-zA-Z]+)+";//正常情况下,域名最多两个
//		String regex = "\\w+@\\w+(\\.\\w+)+";//相对不精确匹配
		String regex = "\\w{5,15}@[a-zA-Z0-9]+(\\.[a-zA-Z]+){1,2}";//正常情况下,域名最多两个
		return address.matches(regex);
	}
}

程序4

模拟网页爬虫

package regular_expression;

import java.io.*;
import java.util.regex.*;
import java.net.*;
/**
 * 模拟网页爬虫
 * @author MCC
 *
 */
public class RegularPractice4 {
	public static void main(String[] args) throws Exception{
		spiderTxtMail("C:\\Users\\MCC\\Desktop\\mail_text.txt", 
				"C:\\Users\\MCC\\Desktop\\mail_result.txt");
		spiderWebMail("https://tieba.baidu.com");
	}
	/*
	 * 文档爬虫
	 */
	public static void spiderTxtMail(String path, String address) throws Exception{
		//建立存储邮箱数据的容器
		StringBuilder sb = new StringBuilder();
		//读取数据源
		File file = new File(path);//判断文件是否存在省略
		BufferedReader br = new BufferedReader(new FileReader(file));
		//将规则封装成正则对象
		String regex = "\\w{6,12}@[a-zA-Z0-9]+(\\.[a-zA-Z]+){1,2}";
		
		Pattern p = Pattern.compile(regex);
		//将规则对象与数据关联
		String line = null;
		while((line=br.readLine())!=null) {
			Matcher m = p.matcher(line);
			while(m.find()) {
				sb.append(m.group()+"\n");
			}
		}
		br.close();
		//将StringBuilder中的内容写入本地
		PrintWriter pw = new PrintWriter(new FileWriter(address), true);
		pw.println(sb.toString());
		pw.close();
	}
	/*
	 * 网页爬虫
	 * 通过关联网页实现
	 */
	public static void spiderWebMail(String address) throws Exception{
		//建立URL对象
		URL url = new URL(address);
		//与网页(服务器)建立连接,不需要使用socket
		URLConnection con = url.openConnection();
		//获取输入流
		InputStream in = con.getInputStream();
		BufferedReader br = new BufferedReader(new InputStreamReader(in));
		//将规则封装成正则对象
		String regex = "\\w{6,12}@[a-zA-Z0-9]+(\\.[a-zA-Z]+){1,2}";
		Pattern p = Pattern.compile(regex);
		//将规则对象与数据关联
		String line = null;
		while((line=br.readLine())!=null) {
			Matcher m = p.matcher(line);
			while(m.find()) {
				System.out.println(m.group());
			}
		}
		br.close();
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值