加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

18.正则表达式

发布时间:2020-12-13 19:34:32 所属栏目:百科 来源:网络整理
导读:一.正则表达式概述 正则表达式用于操作字符串数据 。通过一些特定的符号来体现的。所以我们为了掌握正则表达式,必须要学习一些符号。 正则表达式虽然简化书写,但是阅读性差。所以开发时一般是将正则表达式封装到方法里,然后将要操作的字符串传递到方法里


一.正则表达式概述

正则表达式用于操作字符串数据。通过一些特定的符号来体现的。所以我们为了掌握正则表达式,必须要学习一些符号。

正则表达式虽然简化书写,但是阅读性差。所以开发时一般是将正则表达式封装到方法里,然后将要操作的字符串传递到方法里操作。

二. 正则表达式常用规则

1.字符类

符号

意义

[abc]

ab c(简单类)

[^abc]

任何字符,除了 ab c(否定)

[a-zA-Z]

a z A Z,两头的字母包括在内(范围)

[a-d[m-p]]

a d m p[a-dm-p](并集)

[a-z&&[def]]

de f(交集)

[a-z&&[^bc]]

a z,除了 b c[ad-z](减去)

[a-z&&[^m-p]]

a z,而非 m p[a-lq-z](减去)

2.预定义字符类

符号

意义

.

任何字符(与行结束符可能匹配也可能不匹配)

d

数字:[0-9]

D

非数字: [^0-9]

s

空白字符:[ tnx0Bfr]

S

非空白字符:[^s]

w

单词字符:[a-zA-Z_0-9]

W

非单词字符:[^w]

3. Greedy数量词

X?

X,一次或一次也没有

X*

X,零次或多次

X+

X,一次或多次

X{n}

X,恰好 n

X{n,}

X,至少 n

X{n,m}

X,至少 n 次,但是不超过 m

三. 常见的正则操作

1. 匹配

匹配时一般用String类中的matches(regex)方法,此方法会返回一个boolean值。

2. 切割

使用String类中的方法:String[] split(String regex).

遇到特殊符号,如"。"作为分割点时,可以使用双斜杠".",将特殊符号转换为普通字符。

组的概念:((A)(B)(C)),看括号左边,从左至右编号,组零始终代表整个表达式。

3. 替换

使用String类中的replaceAll()方法

4.获取

将字符串中符合规则的子串取出。

步骤:

  • 将正则表达式封装成对象。Pattern p = Pattern.compile("a*b");
  • 让正则对象与要操作的字符串相关联。Matcher m = p.matcher("aaaaab");
  • 通过Matcher匹配器对象的方法对字符串进行操作。boolean b = m.matches();

代码示例1:定义一个功能对QQ号进行校验。长度为5~15,只能是数字,0不能开头。

<span style="font-size:18px;">//匹配练习1
public class RegexDemo {

	public static void main(String[] args) {

//		checkQQ(qq);
		
		//使用正则表达式
		String qq = "416757768232";
		String regex = "[1-9][0-9]{4,14}";
		
//		boolean b = qq.matches(regex);
//		System.out.println(qq+":"+b);
		
		String str = "aoob";
		String reg = "ao{0,1}b";
		boolean b = str.matches(reg);
		System.out.println(str+":"+b);
	}

	/*
	 * 不用正则表达式的常规方法
	 */
	public static void checkQQ(String qq){
		
		int len = qq.length();
		
		if(len>=5 && len<=15){
			
			if(!qq.startsWith("0")){
				try{
					long l = Long.parseLong(qq);
					
					System.out.println(l+":正确");
				}catch(NumberFormatException e){
					System.out.println(qq+":含有非法字符!");
				}
				
				
			}else{
				System.out.println(qq+":不能0开头");
			}
		}else{
			System.out.println(qq+":长度不符合条件!");
		}
	}
	
	
}
</span>


代码示例二:正则表达式的常见操作

<span style="font-size:18px;">import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexDemo2 {
	
	public static void main(String[] args){
		
		/*
		 * 正则表达式对字符串的常见操作:
		 * 1.匹配
		 * 		String类中的matches()方法
		 * 2.切割
		 * 		split()
		 * 		遇到特殊符号,如"。"作为分割点时,可以使用双斜杠".",将特殊符号转换为普通字符。
		 * 		
		 * 		组:((A)(B)(C)),看括号左边,从左至右编号,组零始终代表整个表达式。
		 * 3.替换
		 * 		使用String类中的replaceAll()方法
		 * 4.获取
		 * 	//将正则进行对象的封装
		 *  Pattern p = Pattern.compile("a*b");
 			//通过正则对象的matcher方法字符串相关联,获取要对字符串操作的匹配器对象Matcher
 			Matcher m = p.matcher("aaaaab");
 			//通过Matcher匹配器对象的方法对字符串进行操作。
 			boolean b = m.matches();
		 * 
		 * 
		 * 匹配,切割,替换,获取这些动作,底层都是Pattern的方法,
		 * 描述正则就这一个对象。只是封装在String类操作更方便。
		 */
		
//		functionDemo_1();
//		functionDemo_2();
//		functionDemo_3();
		functionDemo_4();
	}
	
	//获取
	public static void functionDemo_4() {
		
		String str = "da jia hao,ming tian bu fang jia!";
		
		String regex = "b[a-z]{3}b";//注意,要加上单词边界
		
		//1.将正则封装成对象
		Pattern p = Pattern.compile(regex);
		//2.通过正则对象获取操作字符串的Matcher匹配器
		Matcher m = p.matcher(str);
		//3.查找。find();
		System.out.println(str);

		while(m.find()){//先查找匹配。
			System.out.println(m.group());//查找后才能获取匹配的子序列
		
			System.out.println(m.start()+":"+m.end());//拿到位置。
		}
	}

	//替换
	public static void functionDemo_3() {
		//叠词替换成"#"
//		String str = "zhangsanttttlisimmmmmmmmmwangwu";
//		str = str.replaceAll("(.)1+","#");
		
		//多个叠词替换为一个字符:第二个参数想使用第一个参数正则中的内容, 可以用"$1":获取前一个参数中的第一组。
//		String str = "zhangsanttttlisimmmmmmmmmwangwu";
//		str = str.replaceAll("(.)1+","$1");
//		System.out.println(str);
		
		//号码隐藏
		String tel = "15809673121";
		
		tel = tel.replaceAll("(d{3})d{4}(d{4})","$1****$2");
		System.out.println(tel);
		
	}

	//切割
	public static void functionDemo_2() {
		
//		String str = "zhangsan         lisi          wangwu";
//		String[] names = str.split(" +");

//		String str = "zhangsan.lisi.wangwu";
//		String[] names = str.split(".");	
		
		String str = "zhangsanttttlisimmmmmmmmmwangwu";
		//(.)第一个字符任意,后面的字符和前面一致,所以用()封装,并且自动编号,便于复用。
		//称为组,"(.)1+"将数字转成组标号.不写().则默认为第0组
		String[] names = str.split("(.)1+");
			
	}

	//匹配
	public static void functionDemo_1(){
		
		//匹配手机号码是否正确
		String tel = "15832132342";
		
		String regex = "1[358][0-9]{9}";//使用预定义字符时,反斜杠一律写两个,"d"
		
		boolean b = tel.matches(regex);//使用String类中的matches();
		System.out.println(tel+":"+b);
	}
	
}</span>


四、练习

1.治疗口吃

2.对ip地址排序

3.对邮件地址校验

代码实现:

<span style="font-size:18px;">import java.util.TreeSet;

public class RegexTest {

	public static void main(String[] args) {

		/*
		 * 1.治疗口吃:我。。。我我。。。我我要。。。要要要要。。。要要学学。。。学学。。。学学学。。。编编编。。。编程程。。。程程。。。程程。。。程程
		 * 
		 * 2.对ip地址排序
		 * 
		 * 3.对邮件地址校验。
		 * 
		 */
	
//			test_1();
//			test_2();
			test_3();
		
	}
	
	/*
	 * 3.对邮件地址校验。
	 */
	public static void test_3() {
		
		String mail = "vsfe890@sina.com.cn";
		
		//校验规则
		String regex = "[a-zA-Z0-9_]+@[a-zA-Z0-9]+(.[a-zA-Z]{1,3})+";
		
//		regex = "w+@w+(.w+)+";//1@1.1笼统匹配
		
		boolean b = mail.matches(regex);
		
		System.out.println(mail+":"+b);
	}

	/*
	 * IP地址排序
	 * 
	 * 192.168.10.34 127.0.0.1 3.3.3.3 105.70.11.55
	 * 
	 */
	public static void test_2(){
		
		String ip_str = "192.168.10.34    127.0.0.1     3.3.3.3    105.70.11.55";
		
		//为了让ip可以按照字符串顺序比较,只要让ip的每一段的位数相同。
		//所以,要补零。按照每一位所需最多的0来补,即每一位补两个0.位数多的后面再舍弃。
		ip_str = ip_str.replaceAll("(d+)","00$1");
		
		//然后每一段保留数字3位。
		ip_str = ip_str.replaceAll("0*(d{3})","$1");
		
		
		TreeSet<String> ts = new TreeSet<String>();
		//将ip地址切割
		String[] ips = ip_str.split(" +");
		for(String ip : ips){
//			System.out.println(ip);
			ts.add(ip);
		}
		
		for(String ip : ts){
			System.out.println(ip.replaceAll("0*(d+)","$1"));//输出时再替换
		}
		
	}
	
	
	/*
	 * 治口吃
	 */
	public static void test_1(){
		
		String str = "我...我我...我我要...要要要要......要要学学...学学...学学学...编编编...编程程...程程...程程...程程";
		
		//1.将字符串中的"."替换成空字符。
		str = str.replaceAll(".+","");
//		System.out.println(str);
		
		//2.替换叠词
		str = str.replaceAll("(.)1+","$1");
		System.out.println(str);

	}

}
</span>


4.网页爬虫

这也是一个程序,在互联网中获取指定规则的数据。

下面以爬取邮箱地址为例:

<span style="font-size:18px;">public class RegexTest2 {

	public static void main(String[] args) throws IOException {

		List<String> list  = getMailsByWeb();
		
		for(String mail : list){
			System.out.println(mail);
		}
	}
	
	/*
	 * 爬取网页邮箱。跟本地爬取差不多,只是源改成了网上的。
	 * 
	 */
	public static List<String> getMailsByWeb() throws IOException {
		
//				//获取源文件
//				BufferedReader bufr = new BufferedReader(new FileReader("mail.html"));
				
				URL url = new URL("http:192.168.1.100:8080/myweb/mail.html");
		
				BufferedReader bufr = new BufferedReader(new InputStreamReader(url.openStream()));
				
				List<String> list = new ArrayList<String>();
				//定义规则
				String mail_regex = "w+@w+(.w+)+";
				
				Pattern p = Pattern.compile(mail_regex);

				//读取源文件并根据正则获取数据
				String line = null;
				
				while((line=bufr.readLine())!=null){
					
					Matcher m = p.matcher(line);
					while(m.find()){
						//将符合规则的数据存储到list集合中
						list.add(m.group());
					}
				}
		
		
		return list;
	}

	public static List<String> getMails() throws IOException{
		
		//获取源文件
		BufferedReader bufr = new BufferedReader(new FileReader("mail.html"));
		
		List<String> list = new ArrayList<String>();
		//定义规则
		String mail_regex = "w+@w+(.w+)+";
		
		Pattern p = Pattern.compile(mail_regex);

		//读取源文件并根据正则获取数据
		String line = null;
		
		while((line=bufr.readLine())!=null){
			
			Matcher m = p.matcher(line);
			while(m.find()){
				//将符合规则的数据存储到list集合中
				list.add(m.group());
			}
		}
		
		return list;
	}
}
</span>

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读