【Java基礎】——正則表達式


一、概述

1、正則表達式的概念:符合一定規則的表達式
2、正則表達式的作用:用於專門操作字符串。
3、正則表達式的特點:用一些特定的符號來表示一些代碼操作,這樣可以簡化書寫。
4、正則表達式的利弊
好處:可以簡化對字符串的複雜操作
弊端:符號定義越多,正則越長,閱讀性越差
5、爲什麼要引入正則表達式呢?

二、常用的正則表達式規則

1、字符

x 字符x
\\ 反斜線字符
\On 帶有八進制值 0 的字符 n (0 <= n <= 7)
\Onn 帶有八進制值 0 的字符 nn (0 <= n <= 7)
\Omnn 帶有八進制值 0 的字符 mnn(0 <= m <= 3、0 <= n <= 7)
\xhh 帶有十六進制值 0x 的字符 hh
\uhhhh 帶有十六進制值 0x 的字符 hhhh
\t 製表符 ('\u0009')
\n 新行(換行)符 ('\u000A')
\r 回車符 ('\u000D')
\f 換頁符 ('\u000C')
\a 報警 (bell) 符 ('\u0007')
\e 轉義符 ('\u001B')
\cx 對應於 x 的控制符

2、字符類

[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](減去)

3、預定義字符類

. 任何字符(與行結束符可能匹配也可能不匹配)
\d 數字:[0-9]
\D 非數字: [^0-9]
\s 非數字: [^0-9]
\S 非空白字符:[^\s]
\w 單詞字符:[a-zA-Z_0-9]
\W 非單詞字符:[^\w]

4、邊界匹配器

^ 行的開頭
$ 行的結尾
\b 單詞邊界
\B 非單詞邊界
\A 輸入的開頭
\G 上一個匹配的結尾
\Z 輸入的結尾,僅用於最後的結束符(如果有的話)
\z 輸入的結尾

5、greedy數量詞

X? X,一次或一次也沒有
X* X,零次或多次
X+ X,一次或多次
X{n} X,恰好 n
X{n,} X,至少 n
X{n,m} X,至少 n 次,但是不超過 m

6、組和捕獲

捕獲組可以通過從左到右計算其開括號來編號。例如,在表達式 ((A)(B(C))) 中,存在四個這樣的組:
a)、((A)(B(C)))
b)、\A
c)、(B(C))
d)、(C)
之所以這樣命名捕獲組是因爲在匹配中,保存了與這些組匹配的輸入序列的每個子序列。捕獲的子序列稍後可以通過 Back 引用在表達式中使用,也可以在匹配操作完成後從匹配器獲取。

三、具體操作功能

1、匹配

matches(String regex):用規則匹配整個字符串,只要有一處不符合規則。就返回false。
如下代碼所示:
public class RegexTest1{
	/*
		需求:對手機號碼進行匹配
		分析:手機號碼段13xxxxxxx,15xxxxx,18xxxxxxx
	*/
	public static void main(String[] args){
		String tel = "16900001111";
		//定義電話號碼規則
		String telReg = "1[358]\\d{9}";
		System.out.println(tel.matches(telReg));//結果:false
	}
}

2、切割

split(String regex):根據給定正則表達式的匹配拆分此字符串。
split(String regex, int limit):根據匹配給定的正則表達式來拆分此字符串。
如下代碼所示:
public class RegexTest2{
	public static void main(String[] args){
		String str = "erkktyqqquizzzzzo";
		/*
		按照疊詞完成切割。爲了可以讓規則的結果被重用
		可以將規則封裝成一個組。用()完成。組的出現都有編號。
		從1開始。 想要使用已有的組可以通過  \n(n就是組的編號)的形式來獲取
		*/
		String reg = "(.)\\1+";
		String[] arr = str.split(reg);  
		System.out.println(arr.length);
		for(String s : arr)
		{
			System.out.println(s);
		}
	}
}

3、替換

replaceAll(String regex,String replacement):使用給定的 replacement 替換此字符串所有匹配給定的正則表達式的子字符串。
replaceFirst(String regex,String replacement):使用給定的 replacement 替換此字符串匹配給定的正則表達式的第一個子字符串。
如下代碼所示:
public class RegexTest3{
	public static void main(String[] args){
		String str = "erkktyqqquizzzzzo";
		//正則規則
		String regex = "(.)\\1+";
		str = str.replaceAll(regex,"$1");//$1將重疊的字符替換成單個字母。
		System.out.println(str);//erktyquizo
	}
}

4、獲取

將字符串中符合規則的子串取出。
操作步驟:
①將正則表達式封裝成對象
②讓正則對象與要操作的字符串相關聯
③關聯後,獲取正則匹配引擎
④通過引擎對符合規則的子串進行操作,例如查找find(),取出group()
如下代碼所示:
import java.util.regex.*;

class RegexTest4 
{
	public static void main(String[] args) 
	{
		getDemo();
	}
	public static void getDemo()
	{
		String str = "ming tian jiu yao fang jia le ,da jia。";
		System.out.println(str);
		String reg = "\\b[a-z]{4}\\b";

		//將規則封裝成對象。
		Pattern p = Pattern.compile(reg);

		//讓正則對象和要作用的字符串相關聯。獲取匹配器對象。
		 Matcher m  = p.matcher(str);

		/*
		//其實String類中的matches方法。用的就是Pattern和Matcher對象來完成的。
		//只不過被String的方法封裝後,用起來較爲簡單。但是功能卻單一。
		System.out.println(m.matches());
										
		boolean b = m.find();//將規則作用到字符串上,並進行符合規則的子串查找。
		System.out.println(b);
		System.out.println(m.group());//用於獲取匹配後結果。
		
		System.out.println("matches:"+m.matches()); */
		while(m.find())
		{
			System.out.println(m.group());
			System.out.println(m.start()+"...."+m.end());
		}
	}
}

5、四種功能的選擇

這四種功能,具體的得按照我們的需求來選擇,如:
  • 如果我們只需要指導該字符串是否符合我們的標準,則只需要使用匹配。
  • 如果我們想要將字符串中的某子串變成另一個子串,則使用替換。
  • 如果我們想要將一個字符串按照我們的要求變成多個字符串,則使用切割。
  • 如果想要獲取符合我們需求的子串,則使用獲取。
  • 當然,在將字符串變成符合我們需求的過程中,某些功能可能需要反覆的使用才能達到目標。

四、正則表達式小練習

1、正則表達式小練習一:
/*
需求:
	將下列字符串轉成:我要學編程.
	
	到底用四種功能中的哪一個呢?或者哪幾個呢?
	思路方式:
	1,如果只想知道該字符是否對是錯,使用匹配。
	2,想要將已有的字符串變成另一個字符串,替換。
	3,想要按照自定的方式將字符串變成多個字符串。切割。獲取規則以外的子串。
	4,想要拿到符合需求的字符串子串,獲取。獲取符合規則的子串。
*/
class RegexTest5 
{
	public static void main(String[] args) {
		String str = "我我...我我...我要..要要...要要...學學學....學學...編編編...編程..程.程程...程...程";
		//去除文字段中的.
		str = str.replaceAll("\\.+","");
		System.out.println(str);//我我我我我要要要要要學學學學學編編編編程程程程程程
		//將多個重複的內容變成單個內容
		str = str.replaceAll("(.)\\1+","$1");
		
		System.out.println(str);//我要學編程
	}
}
2、正則表達式小練習二:將ip地址進行地址段順序的排序。
import java.util.*;
public class RegexTest6{
	/*
	將ip地址進行地址段順序的排序。
	還按照字符串自然順序,只要讓它們每一段都是3位即可。
	1,按照每一段需要的最多的0進行補齊,那麼每一段就會至少保證有3位。
	2,將每一段只保留3位。這樣,所有的ip地址都是每一段3位。
	*/
	public static void main(String[] args){
		String ip = "192.68.1.254 102.49.23.013 10.10.10.10 2.2.2.2 8.109.90.30";
		//將每一段需要的最多的0補齊
		ip = ip.replaceAll("(\\d+)","00$1");
		System.out.println(ip);
		//去掉有些段前面多餘的0,保證每一段都是三位。
		ip = ip.replaceAll("0*(\\d{3})","$1");
		System.out.println(ip);
		//將ip按照空格進行切割,並存入數組。
		String[] arr = ip.split(" ");
		//定義一個TreeSet集合,進行自然順序排序。。
		TreeSet<String> ts = new TreeSet<String>();
		//將數組中的元素添加進集合
		for(String s : arr)
		{
			ts.add(s);
		}
		//打印進行排序後的集合中的元素
		for(String s : ts)
		{
			System.out.println(s.replaceAll("0*(\\d+)","$1"));
		}
		/*
			2.2.2.2
			8.109.90.30
			10.10.10.10
			102.49.23.13
			192.68.1.254
		*/
	}
}
3、正則表達式小練習三:網絡爬蟲
/*
網絡爬蟲(蜘蛛)
實際上是一個功能,用於蒐集網絡上的指定信息
需求:可用於收集郵箱,qq號等之類的信息。
應用:如通過關鍵字搜索blog,實際就是使用的“蜘蛛”,通過查找關鍵字獲取相關的blog
*/

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

class  RegexTest7
{
	public static void main(String[] args)throws Exception
	{
		//getFileMail();
		getWebMail();
		
	}

	//獲取網頁中mail
	public static  void getWebMail()throws Exception
	{
		//封裝網頁地址
		URL url=new URL("http://tieba.baidu.com/p/1390896758");
		//連接服務器
		URLConnection conn=url.openConnection();
		//帶緩衝區的網頁讀取流
		BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
		String line=null;
		
		//定義匹配郵件地址的正則表達式
		String regex="\\w+@\\w+(\\.\\w+)+";
		Pattern p=Pattern.compile(regex);//封裝正則表達式
		//讀取網頁數據
		while ((line=br.readLine())!=null)
		{
			//正則關聯數據
			Matcher m=p.matcher(line);
			//尋找匹配郵箱
			while (m.find())
			{
				System.out.println(m.group());//輸出匹配郵箱
			}		
		}	
	}

	//獲取指定文檔中的郵件地址。使用獲取功能。Pattern  Matcher
	public static void getFileMail()throws Exception
	{
		//將文件封裝成對象
		File file=new File("E:\\Java Study\\Practice\\day25\\mail.txt");
		//創建帶緩衝區的讀取流
		BufferedReader br=new BufferedReader(new FileReader(file));
		String line=null;

		//定義正則表達式
		String regex="\\w+@[a-zA-Z]+(\\.[a-zA-z]+)+";
		//創建Pattern對象,封裝正則表達式
		Pattern p=Pattern.compile(regex);

		//讀取文件中數據
		while ((line=br.readLine())!=null)
		{	
			
			//關流字符串
			Matcher m=p.matcher(line);
			while (m.find())//尋找匹配的字符串
			{
				System.out.println(m.group());//輸出匹配的字符串
			}
		}
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章