正则表达式、正则表达式常用功能、匹配器、URL

1正则表达式——功能:匹配、切割、替换

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

作用:用于专门操作字符串。

特点:用一些特定的符号来表示一些代码操作,这样简化了书写。

所以学习正则表达式,就是在学习一些特殊符号的使用。

好处:可以简化对字符串的复杂操作。

弊端:符号定义越多,正则表达式越长,阅读性越差。

正则表达式功能

1,匹配:String类中的matches方法

matches(regex):用正则表达式的规则匹配整个字符串,只要有一处不符合规则,就匹配结束,返回false

2,切割:String类中的split方法

split(regex):根据正则表达式split进行切割当前字符串str

3,替换:String类中的replaceAll方法

replaceAll(regex,newStr):根据正则表达式的规则,用新字符串替换正则表达式定义的字符串。

2正则表达式规则

字符:

x字符x

\\反斜线字符

\0n带有八进制值0的字符n(0<=n<=7)

\0nn带有八进制值0的字符nn(0<=n<=7)

\0mnn带有八进制值0的字符mnn0<=m<=30<=n<=7

\xhh带有十六进制值0x的字符hh

\uhhhh带有十六进制值0x的字符hhhh

\t制表符('\u0009')

\n新行(换行)符('\u000A')

\r回车符('\u000D')

\f换页符('\u000C')

\a报警(bell)('\u0007')

\b匹配一个单词边界,也就是指单词和空格间的位置

\e转义符('\u001B')

\cx对应于x的控制符

字符类:

[abc]abc(简单类)

[^abc]任何字符,除了abc(否定)

[a-zA-Z]azAZ,两头的字母包括在内(范围)

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

[a-z&&[def]]def(交集)

[a-z&&[^bc]]az,除了bc[ad-z](减去)

[a-z&&[^m-p]]az,而非mp[a-lq-z](减去)

预定义字符类:

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

\d数字:[0-9]

\D非数字:[^0-9]

\s空白字符:[\t\n\x0B\f\r]

\S非空白字符:[^\s]

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

\W非单词字符:[^\w]

Greedy数量词:

X?X,一次或一次也没有

X*X,零次或多次

X+X,一次或多次

X{n}X,恰好n

X{n,}X,至少n

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

3组和捕获及正则表达式实例

组合捕获

捕获组可以通过从左到右计算其开括号来编号。例如,在表达式((A)(B(C)))中,存在四个这样的组:

1((A)(B(C)))

2\A

3(B(C))

4(C)

0始终代表整个表达式。

之所以这样命名捕获组是因为在匹配中,保存了与这些组匹配的输入序列的每个子序列。

捕获的子序列稍后可以通过Back引用在表达式中使用,也可以在匹配操作完成后从匹配器获取

与组关联的捕获输入始终是与组最近匹配的子序列。如果由于量化的缘故再次计算了组,

则在第二次计算失败时将保留其以前捕获的值(如果有的话)例如,将字符串"aba"与表达式(a(b)?)+相匹配,

会将第二组设置为"b"。在每个匹配的开头,所有捕获的输入都会被丢弃。

(?)开头的组是纯的非捕获组,它不捕获文本,也不针对组合计进行计数。

应用实例:

需求:对QQ号码进行校验,要求:515位,0不能开头,只能是数字。

原方式:这种方式使用String类中的方法,进行组合完成了需求。但是代码过于复杂。

代码示例:

class RegexDemo{
	public static void main(String[] args){
		checkQQ_1();
		checkQQ();
		demo();
		splitDemo();
		
		String str = "wer1389980000ty12345uiod2345452452454f";//将字符串中数字替换成# 
		replaceAllDemo(str,"\\d{5,}","#");  //\\d{5,}:连续0到9的数字至少5个。
		
		String strr = "erkktytuqqquizzzzzo"; //将叠词替换成相应的单个字符。
		replaceAllDemo(strr,"(.)\\1+","$1");//$1 表示正则表达式中的第一组,即()中的内容,符号$有特殊含义。
	}
	
	//根据正则表达式替换
	public static void replaceAllDemo(String str,String regex,String newStr){
		str = str.replaceAll(regex,newStr);  //String类的replaceAll方法,可以用正则替换 
		System.out.println(str);
	}
	
	//根据正则表达式切割字符串
	public static void splitDemo(){
	 /* String str = "zhangsan....lisi...wangwu";
		String regex = "\\.+";  */ //按照多个点来切割,见正则中的Greedy数量词
		
		String str = "crkkadfddalpezzzzkjgf"; 
		
		String regex = "(.)\\1+";  //按照叠词完成切割,可以将规则封装成一个组,用()括起来。
		                       //组的出现都有编号,从1开始。想要使用已有的组可以通过 \n的形式获取,n是编号
		
		String[] arr = str.split(regex); //根据叠词分割
		for(String s : arr){
			System.out.println(s);
		}
	}
	
	//正则表达式定义规则:字符,字符类,预定义字符类,Greedy数量词
	public static void demo(){
		String str = "b9";
		
		String regex = "[a-zA-Z]\\d";
		
		boolean b = str.matches(regex); //匹配
		System.out.println(b);
	}
	
	//正则表达式方式
	//boolean matches(String regex); 告知此字符串是否匹配给定的正则表达式。 
	public static void checkQQ(){
		String qq = "275150374";
		
		String regex = "[1-9][0-9]{4,14}";
		
		boolean flag = qq.matches(regex); //匹配
		if(flag)
			System.out.println(qq+"...is ok");
		else
			System.out.println(qq+"...不合法");
	}
	
	//原方式,不使用正则表达式。
	public static void checkQQ_1(){
		String qq = "111111111111111";
		int len = qq.length();
		
		if(len>=5 && len<=15){
			if(!qq.startsWith("0")){
							
				char[] arr = qq.tocharArray();
				boolean flag = true;
				
				for(int x=0; x<arr.length; x++){
					if(!(arr[x]>='0' && arr[x]<='9')){
						flag = false;
						break;
					}
				}
				if(flag)
					System.out.println("QQ: "+qq);
				else
					System.out.println("出现非法字符");
			}
			else{
				System.out.println("不能以0开头");
			}
		}
		else{
			System.out.println("长度错误");
		}
	}
}

4正则表达式功能——获取(匹配器Matcher)

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

操作步骤:

1,将正则表达式封装成对象。

2,让正则对象和要操作的字符串相关联。

3,关联后,获取正则匹配引擎。

4,通过引擎,对符合规则的子串进行操作,比如取出。

代码示例:

import java.util.regex.*;

class RegexDemo2 {
	public static void main(String[] args){
		getDemo();
	}
	public static void getDemo(){
		String str = "ming tian jiu yao fang jia la";
		
		//正则表达式,\b是单词边界符。
		String regex = "\\b[a-z]{4}\\b"; 
		
		//将正则封装成对象。
		Pattern p = Pattern.compile(regex);
		
		//让正则对象和要作用的字符串相关联。获取匹配器对象。
		Matcher m = p.matcher(str);
		
	  //str.matches(regex);//其实String类中的matches方法,用的就是Pattern和Matcher对象来完成的,
						   //只不过被String的方法封装后,用起来较为简单,但是功能却单一。
		
		while(m.find()){  //判断是否有符合匹配器的子串。
			System.out.println(m.group());  //返回由以前匹配操作所匹配的输入子序列,返回匹配结果。
			
			//匹配的子串的开始脚标和结束脚标,包含头不包含尾。
			System.out.println("位置:"+m.start()+"..."+m.end()); 
		}
	}
}

匹配结果:


5正则表达式练习★

练习1

需求:将下列字符串转换成:我要学编程

到底用四种功能中的哪一个呢?或者哪几个呢?

思路方式:

1,如果只想知道该字符是对还是错,使用匹配。

2,想要将已有的字符串变成另一个字符串,替换。

3,想要按照自定的方式将字符串变成多个字符串,切割、获取规则以外的子串。

4,想要拿到符合需求的字符串子串,获取获取符合规则的子串。

练习2

需求:将ip地址进行地址段顺序的排序。

192.68.1.254102.49.23.1310.10.10.102.2.2.28.109.30.90

还按照字符串自然顺序,只要让它们每一段都是3位即可。

1,按照每一段需要的最多的0进行补齐,那么每一段至少保证有3位。

2,将每一段只保留3位。这样,所有的ip地址段都是每一段3位。

练习3

需求:对邮件地址进行校验。

代码示例:

import java.util.regex.*;
import java.util.*;

class RegexTest{
	public static void main(String[] args){
		test_1();
		ipSort();
		checkMail();
	}
	
	public static void test_1(){
		String str = "我我...我我...我要..要要...要要...学学学..学学..编编...编编..编程..程程.程程";
		
		/* 将已有字符串变成另一个字符串。使用替换功能。
		1,可以先将 “.”去掉。
		2,再将多个重复的内容变成单个内容。 */
		
		str = str.replaceAll("\\.+","");
		System.out.println(str);
		
		//$1 表示正则表达式中的第一组,即()中的内容,符号$有特殊含义.
		str = str.replaceAll("(.)\\1+","$1");
		System.out.println(str);
	}
	
	public static void ipSort(){
		String ip = "192.68.1.254  102.49.23.13  10.10.10.10  2.2.2.2  8.109.30.90";
		
		ip = ip.replaceAll("(\\d+)","00$1"); //每一段都补两个0 
		System.out.println(ip);
		
		ip = ip.replaceAll("0*(\\d{3})","$1"); //每一段保留三位 
		System.out.println(ip);
		
		String[] arr = ip.split("  ");
		
		TreeSet<String> ts = new TreeSet<String>(); //TreeSet集合,自然排序 
		for(String s : arr){
			ts.add(s);
		}
		for(String s : ts){
			System.out.println(s.replaceAll("0*(\\d+)","$1"));  //把开头的0去掉 
		}
	}
	
	public static void checkMail(){
		String mail = "abc123@sina.com";
		
		String reg = "[a-zA-Z0-9_]+@[a-zA-Z0-9]+(\\.[a-zA-Z]+)+";//较为精确的匹配
		String regex = "\\w+@\\w+(\\.\\w+)+";  //相对不太精确的匹配
		
		System.out.println(mail.matches(regex));
	}
}

6抓取电子邮件地址和URL

获取指定文档中的邮件地址。

使用获取功能PatternMatcher

URLjava.net包的URL类、URLConnection

调用URL对象的openConnection()方法创建连接对象,返回URLConnection对象。

URLConnection类中

getInputStream():返回从此打开的链接读取数据的读取流,读取URL资源。

getOutputStream():返回写入到此链接输出流。

代码示例:

import java.util.regex.*;
import java.io.*;
import java.net.*;

class RegexTest2 {
	public static void main(String[] args) throws Exception{
		getMails();
		getMails_1();
	}
	
	//从文档中抓取电子邮件地址
	public static void getMails() throws Exception{
		BufferedReader bufr = 
			new BufferedReader(new FileReader("e:\\mail.txt"));
		
		String mailregex = "\\w+@\\w+(\\.\\w+)+";
		Pattern p = Pattern.compile(mailregex);//将正则封装成对象
		
		String line = null;		
		while((line=bufr.readLine())!=null){
			Matcher m = p.matcher(line); //正则对象和字符串关联,获取匹配器
			
			while(m.find()){ //是否有符合匹配器的子串。
				System.out.println(m.group()); //返回匹配的子序列,返回匹配结果。
			}
		}
	}
	
	//从网页中抓取电子邮件地址
	public static void getMails_1() throws Exception{
		URL url = new URL("http://192.168.0.100:8080/myweb/mail.html");
		
		URLConnection conn = url.openConnection(); //创建连接对象。
		
		BufferedReader bufIn = 
			new BufferedReader(new InputStreamReader(conn.getInputStream())); //读取URL资源的读取流
		
		String mailregex = "\\w+@\\w+(\\.\\w+)+";
		Pattern p = Pattern.compile(mailregex); //把正则表达式封装成对象
		
		String line = null;		
		while((line=bufIn.readLine())!=null){
			Matcher m = p.matcher(line); //创建匹配器,关联正则对象和字符串
			
			while(m.find()){  //判断是否有匹配的子串
				System.out.println(m.group()); //返回匹配结果
			}
		}
	}
}

相关文章

一、校验数字的表达式 1 数字:^[0-9]*$ 2 n位的数字:^d{n}$ 3 至少n位的数字:^d{n,}$ 4 m-n位的数字...
正则表达式非常有用,查找、匹配、处理字符串、替换和转换字符串,输入输出等。下面整理一些常用的正则...
0. 注: 不同语言中的正则表达式实现都会有一些不同。下文中的代码示例除特别说明的外,都是使用JS中的...
 正则表达式是从信息中搜索特定的模式的一把瑞士军刀。它们是一个巨大的工具库,其中的一些功能经常...
一、校验数字的表达式 数字:^[0-9]*$ n位的数字:^\d{n}$ 至少n位的数字:^\d{n,}$ m-n位的数...
\ 将下一字符标记为特殊字符、文本、反向引用或八进制转义符。例如,“n”匹配字符“n”。“\n...