1. 程式人生 > >正則表示式入門知識+用它實現在一個網頁中獲取所有的連結地址

正則表示式入門知識+用它實現在一個網頁中獲取所有的連結地址

大家可以加群一起學習:688160561

概念:正則表示式是一種電腦科學的概念、它通常用來檢索和替換那些符合規則的文字或者字串。現在很多的程式設計語言計都支援利用正則表示式來進行字串的操作,有java、c++、python、javascript、perl、php等。

作用:

 1 給定的字串是否符合正則表示式

 2 通過正則表示式可以從字串中獲取我們想要的特定部分

規則:

開始與結束:^、$

表示匹配個數:+(1次以上)、?(0或者1次)、|、< >、(注:前面四個元字元並不是所有的軟體都支援)*、{n}、{n,}、{n,m}、\p{P}(javascript不支援)、.點(除\n\r外單個字元) *(任意次)

表示匹配範圍:[xyz]、[^xyz]、[a-z]、[^a-z]

特殊字元時用:\    "\\d"

大小寫:(大寫表示否,小寫表示是) \b (單詞邊界)\B  \d (數字)\D \s (不可見字元)\S \w (包含下劃線字元)\W

不可見字元:\f、\r、\n、 \t、\v

組合:\cx  \xn(十六進位制 ascII編碼) \num、\n、\nm、\nml(八進位制編碼)、\un(十六進位制unicode編碼)中文

非獲取匹配:(?:pattern)、(?=pattern)(匹配pattern的前面部分)、(?!pattern)、(?<=pattern)(匹配pattern的後面部分)、(?<!pattern)(否定)

幾個例子快速認識:

1.驗證使用者名稱和密碼:("^[a-zA-Z]\w{5,15}$")正確格式:"[A-Z][a-z]_[0-9]"組成,並且第一個字必須為字母6~16位;
2.驗證電話號碼:("^(\\d{3,4}-)\\d{7,8}$")正確格式:xxx/xxxx-xxxxxxx/xxxxxxxx;
3.驗證手機號碼:"^1[3|4|5|7|8][0-9]\\d{8}$";
4.驗證身份證號(15位或18位數字):"\\d{14}[[0-9],0-9xX]";
5.驗證Email地址:("^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$");

正則引擎:

NFA引擎(以表示式為準,容易操作,但速度慢,,為了匹配正則表示式的所有可能的擴充套件,可能對相同字元匹配多次,所以採用貪婪的回溯演算法),java python perl 

DFA引擎(以文字為準,速度較快,但不好控制,線上性狀態下執行,不要求回溯)。awk grep mysql程式都採用這個引擎。

JAVA類庫java.util.regex包

Pattern類與matcher類

pattern類

compile(String regx)  引數正則表示式  返回值  pattern物件  功能

split(String str)  引數字串  返回值string [] 返回被regx分隔的字串陣列

matches(String regex,String   str) 靜態方法,返回boolean 用於快速匹配,只匹配一次,匹配全部字串

matcher(String str)返回matcher類的物件 由pattern類物件呼叫

matcher類

pattern()返回pattern類物件,也就是該物件建立matcher類物件的

matches()用於匹配整個字串 成功返回true

lookAt()對前面的字串匹配 成功返回true

find()對字串進行匹配,匹配到的子字串可以在任何位置。成功返回true

start()返回匹配到的子字串在字串中的索引位置

end()返回匹配到的子字串的最後一個字元在字串中的索引位置

group()返回匹配到的子字串

還有過載它們的方法start(i)、end(i)、group(i)用於分組操作,groupCount()返回分組數  即有多少個()被匹配了

注意:每次執行一次start end group的值都會發生變化的 ,並且用它們之前一定要確定已經匹配成功了,即find lookAt matches方法返回成功true,否則發生錯誤java.lang.IllegalStateException。

應用:

public class TCPSever {
	 /** http協議結構
	   * http請求包話三個部分:
	   * 1、請求行
	   *   組成:method request-url http-version crlf
	   *   get / www.baidu.com http/1.1 \r\n
	   * 2、訊息報頭
	   *   型別:
	   *   HOST: WWW.baidu.com \r\n
	   * 3、請求正文
	   *     \r\n
       *   http響應由三部分組成
       *   1、狀態行
       *   2、訊息報頭
       *   3、響應正文
       * 
       */
	public String getContent(){
		String str=null;
		try {
			//
			//建立客戶端物件
			System.out.println("開始建立客戶端物件……");
			Socket client=new Socket("www.baidu.com",80);			
			 
			//建立輸入、輸出流物件
			InputStream in=client.getInputStream();
			OutputStream out=client.getOutputStream();
			//位元組流轉為字元流,再把字元流寫入緩衝區
			BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
					out));
		    BufferedReader br = new BufferedReader(new InputStreamReader(
					in));
					bw.write("GET / HTTP/1.1\r\n");
					bw.write("Host: www.baidu.com\r\n");
					bw.write("\r\n");
					bw.flush();					
					String line = null;
					
      
			StringBuffer bf=new StringBuffer(4000);
			
			int sum=0;
			System.out.println("從百度中請求到的資料是:");
			while(true){
				if((line=br.readLine())!=null)
				{    bf.append(line+"\n\r");
					  sum++;			
				}					    
				else
				break;				
			}
			  //把緩衝區的字串轉為字串
			   String str1=new String(bf);
			   //修改編碼,解碼,因為gbk是eclipse預設的編碼,改為UFT-8,符合伺服器那邊要求
			   //當然我這樣做為了方便大家瞭解編碼解碼過程,不然就直接在while迴圈輸出了,可以從
			   //伺服器那邊響應報頭知道文字的編碼格式為UTF-8
			    str=new String(str1.getBytes("gbk"),"UTF-8");
			 //  System.out.print("有"+sum+"行\r\n"+"緩衝區長度"+bf.length()+"\r\n"+str);
			   /*
			    * 
			    */
				br.close();
				bw.close();
				in.close();
				out.close();
				client.close();
			
		 } catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
          return str;
		
	}
	public void getHttp(String regex,String str){
		//利用pattern和matcher類實現
		 System.out.println(str);
		Pattern pattern=Pattern.compile(regex);
		   Matcher matcher=pattern.matcher(str);
		   int sum=0;
		   //沒必要用這個List,我只是為了測試
		   List str1=new Vector();
		   while(matcher.find()){
			   sum++;
			   str1.add(matcher.group());
			   System.out.println("第"+sum+"個"+matcher.group()+" "+"起始位置"+matcher.start()+"  "+"結束位置"+matcher.end());
		   }
		  
		  //System.out.println(s);
	}
	public static void main(String args[]){
		TCPSever tcp=new TCPSever();
		//這個http響應返回的內容當做一個字串,所以別用^或者$
		//字串
		      String str="href=\"(http://|//)[^\\s]*\"";
		      String content=tcp.getContent();		    
		      tcp.getHttp(str,content);
			}
}
執行結果:

javascript

javascript裡通過建立new REgExp(pattern,attributes)物件來呼叫它對應的函式和屬性來支援正則表示式。

屬性:

global全域性匹配 匹配多次

ignoreCase忽略大小寫

lastIndex 執行一次test    移動到匹配位置並加+ 不夠從零開始

multiline 忽略^ $執行多行首尾

source

方法:

compile 重新編譯正則表示式

exec檢索字串指定的值,並返回找到的值和確定它的位置

test 檢索字串指定的值,找到返回true


String物件支援正則表示式的方法

search(regex)檢索與正則表示式匹配的值  引數:可以是字串中的匹配的子字串或中RegExp物件  返回第一個匹配的子字串在字串中的索引位置,它忽略g和lastIndex屬性,也就是它不執行全域性匹配和總是從頭開始匹配

match( regex)找到一個或者多個與正則表示式匹配的值   匹配返回值不匹配返回null  /g全域性匹配  返回與它匹配的所有子字串。

replace (regex,String str)替換與正則表示式匹配的字串    即用str替換滿足用正則表示式匹配到的子字串

split(string str,[len])把字串分割成字串陣列   str可以是字元或者是正則表示式/^\\d+/(不是RegExp物件),[len]表示可選,是限定返回陣列的長度

注意:如果正則表示式與字串函式同樣能達到效果就用字串函式,效率高。

應用

資料庫

以後有時間再補上。。。

oracle

mysql

mongdb

sql server 2005