正則表達式(Regular Expression)基礎知識
一、開發中使用流程:
- -分析要匹配的數據 寫出測試用的典型數據
- -在工具軟件中進行匹配測試
- -在程序中調用通過測試的正則表達式 (有些高級語法有些區別)
二、工具軟件RegexBuddy的使用
三、語法
1)字符
-普通字符
字母、數字、漢字、下劃線、以及沒有特殊定義的標點符號都是普通字符。直接匹配與之相同的字符
-簡單的轉義字符
\n 換行符
\t 製表符
\\ \本身
其他都是類似 \^ \$ \( 這樣匹配這些字符本身的(還有 ) { } ? + * | [ ] )
-標準字符集合(常用!!!)
能夠與多種字符匹配的表達式 注意區分大小寫 大寫是相反的意思
\d 任意一個數字,0-9中任意一個 \D 表示所有非數字
\w 任意一個字母或下劃線,也就是A-Z、a-z、0-9、_ 、中的任意一個
\s 包括空格、製表符、換行符等空白字符中的任意一個
. 小數點可以匹配任意一個字符(除了換行符)。如果要匹配包括“\n”在內的所有字符,一般用 [\s\S]
-自定義字符集合
[]方括號匹配方式 ,能夠匹配方括號中任意一個字符。^符號在方括號裏表示 取反 方括號外表示零寬標記,見後面
如: [ab5@] 匹配 “a”或“b”或“5”或“@”
[^abc] 匹配“a”、“b”、”c“之外的任意一個字符
[f-k] 匹配“f”-“k”之間的任意一個字母
[^A-F0-3] 匹配“A”-“F”,“0”-“3”之外的任意一個字符
正則表達式的特殊符號,被包含到中括號中則失去其特殊意義(就表示自身這個字符),除了^,-之外。
標準字符集合,除小數點外,如果被包含於中括號,自定義字符集合將包含該集合。比如: [\d.\-+]將匹配:數字、小數點、+、-
2)量詞Quantifier(常用!!!)
修飾匹配次數的特殊符號
{n} 表達式重複n次 如:\d{6} 匹配6位數字 \d\d{6} 匹配7位數字 {\d\d}{6} 匹配12位數字
{m,n} 表達式至少重複m次,最多重複n次
{m,} 至少重複m次
? 匹配表達式0次或1次 ,相當於{0,1} 如:a\d{0,1}b a\d?b 是等價的
+ 表達式至少出現1次,相當於{1,} 如:a\d+b
* 表達式不出現或出現任意次,相當於{0,}
匹配次數中的貪婪模式 (匹配字符數越多越好,默認的!!!)如\d{3,6} 會優先匹配 6位數字
匹配次數中的非貪婪模式 (匹配字符越少越好,修飾匹配次數的特殊符號後再加上一個“?”號)
3)字符邊界(零寬,不佔長度)
-(本組標記匹配的不是字符而是位置,符合某種條件的位置)
^ | 與字符開始的地方匹配 |
$ | 與字符結束的地方匹配 |
\b | 匹配一個單詞邊界 |
-\b匹配這樣一個位置:前面的字符和後面的字符不全是\w (全是的就不匹配)
如:^i 匹配 i開頭的位置 i$ 匹配i結束的位置 hello\b 匹配前後不全是\w表示的hello
4)匹配模式
-IGNORECASE
忽略大小寫 默認情況下正則表達式區分大小寫(Case Insensitive)
-SINGLELINE
單行模式 整個文本看作一個字符串,只有一個開頭,一個結尾。使得小數點“.”可以匹配包含換行符(\n)在內的任意字符
-MULTILINE
多行模式 每行都是一個字符串,都有開頭和結尾。在指定了此模式後,如果需要僅匹配字符串開始和結束位置,可以使用\A和\Z
如:\Ai匹配 第一行第一個i ^i 匹配每一行第一個的i i$匹配每一行的最後一個i i\Z 匹配整個文檔最後一個i
5)選擇符和分組
| 分支結構 表示“或” 如 h|a hello|world
() 捕獲組
-在被修飾匹配次數的時候,括號中的表達式可以作爲整體被修飾
-取匹配結果的時候,括號中的表達式匹配到的內容可以被單獨地編號
-每一對括號會被分配一個編號,使用()的捕獲根據左括號的順序從1開始自動編號。捕獲元素編號爲零的第一 個捕獲是由整個正則表達式模式匹配的內容
(?:Expression) 非捕獲組
-一些表達式中,不得不使用(),但又不需要保存()中的子表達式匹配的內容,這時可以用非捕獲組來抵消使用()帶來的副作用。節省內存。
6)反向引用(\nnn)\nnn表示可以匹配多位數字
-每一對()會分配一個編號,使用()的捕獲根據左括號的順序從1開始自動編號。
-通過反向引用,可以對分組已捕獲的字符串進行引用。
如 ([a-z]{2})\1 中的\1 代表第一個組裏的內容,匹配到gogo,toto,dodo這樣的字符串。
()()() 捕獲的內容分別用\1 \2 \3 編號以左括號爲準。
7)預搜索(零寬斷言)(也叫環視)
只進行子表達式的匹配,匹配內容不計入最終的匹配結果,是零寬度。判斷當前位置的前後字符,是否符合指定的條件,但不匹配前後的字符,是對位置的匹配。exp表示表達式
(?=exp) | 斷言自身出現的位置的後面能匹配表達式exp |
(?<=) | 斷言自身出現的位置的前面能匹配表達式exp |
(?!exp) | 斷言此位置的後面不能匹配表達式exp |
(?!exp) | 斷言此位置的前面不能匹配表達式exp |
如:[a-z]+(?=ing) 匹配ing結尾的字符串,但不匹配ing本身
[a-z]+(?=\d+) 匹配數字結尾的字符串
四、常用的一些正則表達式
電話號碼驗證(包含固話和手機號,不能確認號碼一定存在,只能匹配格式)
-(1)電話號碼由數字和“-”構成
-(2)電話號碼爲7-8位
-(3)如果電話號碼中包含有區號,那麼區號爲3位或4位,首位是0
-(4)區號用“-”和其他部分隔開
-(5)移動電話號碼爲11位
-(6)11位移動電話號碼的第一位和第二位爲“13”“15”“18”
固話 0\d{2,3}-\d{7,9} 手機號 1[35789]\d{9}
電子郵箱地址驗證
-1.用戶名:字母、數字、中劃線、下劃線組成
-2.@
-3.網址:字母、數字組成
-4.小數點。
-5.組織域名:2-4位字母組成
-不區分大小寫
[\w\-]+@[a-z0-9A-Z]+(\.[A-Za-z]{2,4}){1,2} 如:[email protected]
匹配中文字符 | [\u4e00-\u9fa5] |
匹配空白行 | \n\s*\r |
匹配HTML標記 | <(\S*?)[^>]*>.*?</\1>|<.*?/> |
匹配首尾空白字符 | ^\s*|\s*$ |
匹配Email地址 | \w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)* |
匹配網址URL | [a-zA-Z]+://[^\s]* |
匹配國內電話號碼 | \d{3}-\d{8}|\d{4}-\d{7} |
匹配騰訊QQ號 |
[1-9][0-9]{4,} |
匹配中國郵政編碼 | [1-9]\d{5}(?!\d) |
匹配身份證 | \d{15}|\d{18} |
匹配ip地址 | \d+\.\d+\.\d+\.\d+ |
五、工作學習中各種環境的使用
開發環境和文本編輯器 eclipse、Notepad++、Editplus、UltraEdit
數據庫中 MySQL5.5以上 Oracle10g以上
例如 :
SELECT prod_name FROM products WHEREprod_name REGEXP '.000'(.表示匹配任意字符,整體表示匹配000結尾的)
Notepad++ 搜索 Ctrl+F
eclipse裏search中可以使用。
六、JAVA程序中使用正則表達式
相關包在java.util.regex包下面
類Pattern:
-正則表達式的編譯表示形式
-Pattern p = Pattern.compile(r,int);//建立正則表達式,並啓用相應模式
類Matcher
-通過揭示Pattern對character sequence執行匹配操作的引擎
-Matcher m = p.matcher(str);//匹配str字符串
JAVA中遇到\ ,都要再加一個\.即正則裏的\w+在java裏是\\w+
Demo01
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 測試正則表達式對象的基本用法
* @author Administrator
*
*/
public class Demo01 {
public static void main(String[] args) {
//在這個字符串:asfsdf23323,是否符合指定的正則表達式:\w+
//表達式對象
Pattern p = Pattern.compile("\\w+");
//創建Matcher對象
Matcher m = p.matcher("asfsdf2&&3323");
// boolean yesorno = m.matches(); //嘗試將整個字符序列與該模式匹配
// System.out.println(yesorno);
// boolean yesorno2 = m.find(); //該方法掃描輸入的序列,查找與該模式匹配的下一個子序列
// System.out.println(yesorno2);
// System.out.println(m.find());
// System.out.println(m.group());
// System.out.println(m.find());
// System.out.println(m.group());
while(m.find()){
System.out.println(m.group()); //group(),group(0)匹配整個表達式的子字符串,效果一樣的
System.out.println(m.group(0));
}
}
}
Demo02
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 測試正則表達式對象中分組的處理
* @author Administrator
*
*/
public class Demo02 {
public static void main(String[] args) {
//在這個字符串:asfsdf23323,是否符合指定的正則表達式:\w+
//表達式對象
Pattern p = Pattern.compile("([a-z]+)([0-9]+)");
//創建Matcher對象
Matcher m = p.matcher("aa232**ssd445*sds223");
while(m.find()){
System.out.println(m.group()); //group(),group(0)匹配整個表達式的子字符串
System.out.println(m.group(1));
System.out.println(m.group(2));
}
}
}
Demo03
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 測試正則表達式對象的替換操作
* @author Administrator
*
*/
public class Demo03 {
public static void main(String[] args) {
//表達式對象
Pattern p = Pattern.compile("[0-9]");
//創建Matcher對象
Matcher m = p.matcher("aa232**ssd445*sds223");
//替換
String newStr = m.replaceAll("#");
System.out.println(newStr);
}
}
Demo04
import java.util.Arrays;
/**
* 測試正則表達式對象的分割字符串的操作
* @author Administrator
*
*/
public class Demo04 {
public static void main(String[] args) {
String str = "a232b4334c3434";
String[] arrs = str.split("\\d+");
System.out.println(Arrays.toString(arrs));
}
}
WebSpiderTest網絡爬蟲小例子
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 網絡爬蟲取鏈接
* @author Administrator
*
*/
public class WebSpiderTest {
/**
* 獲得urlStr對應的網頁的源碼內容
* @param urlStr
* @return
*/
public static String getURLContent(String urlStr,String charset){
StringBuilder sb = new StringBuilder();
try {
URL url = new URL(urlStr);
BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream(),Charset.forName(charset)));
String temp = "";
while((temp=reader.readLine())!=null){
sb.append(temp);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
public static List<String> getMatherSubstrs(String destStr,String regexStr){
Pattern p = Pattern.compile(regexStr); //取到的超鏈接的地址
Matcher m = p.matcher(destStr);
List<String> result = new ArrayList<String>();
while(m.find()){
result.add(m.group(1));
}
return result;
}
public static void main(String[] args) {
String destStr = getURLContent("http://www.163.com","gbk");//使用GBK解碼,在網頁源碼開頭中可以看到
// Pattern p = Pattern.compile("<a[\\s\\S]+?</a>"); //取到的超鏈接的整個內容
List<String> result = getMatherSubstrs(destStr, "href=\"([\\w\\s./:]+?)\""); //取到具體的鏈接地址
for (String temp : result) {
System.out.println(temp);
}
}
}