模式 |
匹配的內容(含意) |
字符類 |
|
[abc] |
a、b 或 c(簡單類) |
[^abc] |
任何字符,除了 a、b 或 c(否定) |
[a-zA-Z] |
a 到 z 或 A 到 Z,兩頭的字母包括在內(范圍) |
[a-d[m-p]] |
a 到 d 或 m 到 p:[a-dm-p](并集) |
[a-z[def]] |
d、e 或 f(交集) |
[a-z[^bc]] |
a 到 z,除了 b 和 c:[ad-z](減去) |
[a-z[^m-p]] |
a 到 z,而非 m 到 p:[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] |
邊界匹配器 |
|
^ |
行的開頭 |
$ |
行的結尾 |
\b |
單詞邊界 |
\B |
非單詞邊界 |
\A |
輸入的開頭 |
\G |
上一個匹配的結尾 |
\Z |
輸入的結尾,僅用于最后的 結束符 (如果有的話) |
\z |
輸入的結尾 |
數量詞(Greedy策略) |
|
X? |
X,一次或一次也沒有 |
X* |
X,零次或多次 |
X+ |
X,一次或多次 |
X{n} |
X,恰好 n 次 |
X{n,} |
X,至少 n 次 |
X{n,m} |
X,至少 n 次,但是不超過 m 次 |
邏輯運算符 |
|
XY |
X 后跟 Y |
X|Y |
X 或 Y |
(X) |
X,作為 捕獲組 |
這些常用的符號在各種編程語言的正則表達式中含意基本相同 ( 因為正則表達式的思想是相同的 ) ,所以都可以用來參數。但不同的語言可能會有一些細小的差別,如果要針對各種編程語言,想有更精確和權威的說明,可參考其官方文檔:
C++(VS2013編譯器 ) : http://msdn.microsoft.com/zh-cn/library/bb982727.aspx#grammarsummary
Java : http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html
JavaScript : http://www.w3school.com.cn/jsref/jsref_obj_regexp.asp
正則表達式的使用
下面從常見的需求出發講述 C++ 、 Java 和 JavaScript 中正則表達式的使用
C++中的正則表達式
C++ 中正則表達式主要有三種實現方式: C 語言的實現方式 (C regex) , C++ 標準庫的實現 (C++ regex) , Boost 庫的實現 (boost regex) 。 C regex 的方式是一種面向過程的編程方式,使用起來不太方便; C++ regex 的方式因為是標準庫的一部分,所以可以直接使用 ( 好像 Linux 平臺下不支持 ) ,但 C++ regex 非常難用,語法要求比較嚴格,而且好多默認的選項和我們正常的想法不一樣; Boost 是一個開源的第三方庫,這個庫非常優秀,廣泛應用于 C++ 的項目開發中, boost regex 非常靈活好用, C++ 開發時是大家推崇的一種方式。
關于 boost regex 的用法,在后繼的文章將會進一步介紹,現在以 C++ regex 的方式列舉一個使用樣例。
1.驗證ip 地址
#include regex> #include iostream> #include string> bool IsIpV4Address(const std::string strIp) { //驗證IP地址的模式,這里"\."中的"\"是轉義字符,表示這是一個. const std::regex pattern("(\\d{1,3}){1}\.(\\d{1,3}){1}\.(\\d{1,3}){1}\.(\\d{1,3}){1}"); //匹配驗證 return std::regex_match(strIp, pattern); } int main() { std::string strIp1 = "134.34.34.4";//192.168.1.1 std::string strIp2 = "192.168.255"; std::cout strIp1 " : " (IsIpV4Address(strIp1) ? "valid" : "invalid") std::endl; std::cout strIp2 " : " (IsIpV4Address(strIp2) ? "valid" : "invalid") std::endl; return 0; }
Java中的正則表達式
1.驗證一個字符串是否為URL
public static boolean isUrl(String text) { String regex = "^http://([\\w-]+.)+[\\w-]+(/[\\w-./?%=#]*)?$"; return text.matches(regex); }
2.判斷一個文本中有多少個URL ,并將所有的 URL 加上超鏈接 .
如以下文本:
C++(VS 2013 編譯器 ) : http://msdn.microsoft.com/zh-cn/library/bb982727.aspx#grammarsummary
Java : http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html
JavaScript : http://www.w3school.com.cn/jsref/jsref_obj_regexp.asp
添加鏈接后變成:
C++(VS 2013 編譯器 ) : a href= ” http://msdn.microsoft.com/zh-cn/library/bb982727.aspx#grammarsummary
” > http://msdn.microsoft.com/zh-cn/library/bb982727.aspx#grammarsummary /a>
Java : a href= ” http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html
” > http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html /a>
JavaScript : a href= ” http://www.w3school.com.cn/jsref/jsref_obj_regexp.asp
” > http://www.w3school.com.cn/jsref/jsref_obj_regexp.asp /a>
/** * 給一個字符串添加鏈接 * @param text 要添加鏈接的字符串 * @param url 鏈接的URL * @return 添加鏈接后的字符串 */ public static String AddHref(String text, String url) { return "a href=\"" + url + "\">" + text + "/a>"; } /** * 查找文本中的URL字符串,并將其添加鏈接 * @param text 需要查找的文本 * @return 添加鏈接后的文本 */ public static String AddLinkToText(String text) { Pattern pattern = Pattern.compile("http://([\\w-]+.)+[\\w-]+(/[\\w-./?%=#]*)?"); Matcher matcher = pattern.matcher(text); StringBuffer sb = new StringBuffer(); //定義一個字符緩沖區,用于保存新的文本 while (matcher.find()) { String matchedSubStr = matcher.group(); //提取出查找到的子串 matcher.appendReplacement(sb, AddHref(matchedSubStr, matchedSubStr)); //將找到的子串添加鏈接后塞到字符緩沖區內 } matcher.appendTail(sb); return sb.toString(); }
JavaScript中的正則表達式
JavaScript 中的正則表達式是通過 RegExp 對象實現的。 RegExp 對象的創建有三種方式:
精簡方式:
/pattern/attributes
new 方式:
new RegExp(pattern, attributes);
函數調用的方式:
RegExp(pattern, attributes);
參數pattern可以是一個模式串,也可以是一個RegExp對象,如果pattern本身就是RegExp的對象,則attributes參數將不起作用(新創建的對象的必發與pattern對象相同。),需要省略,如果不省略會拋TypeError 異常。
參數attributes有三種屬性"g"、"i" 和 "m",分別用于指定全局匹配、區分大小寫的匹配和多行匹配。
RegExp主要有三個方法:
compile |
編譯正則表達式,可用于改變和重新編譯正則表達式。 |
exec |
檢索字符串中指定的值。返回找到的值,并確定其位置。 |
test |
檢索字符串中是否有指定的值。返回 true 或 false 。 |
1.驗證字符串是否為數字
script type="text/javascript"> function isNumber(text) { var pattern = new RegExp("^\\d*$"); return pattern.test(text); } var value1 = "1234"; document.write(value1 + " is Numed:" + isNumber(value1)); /script>
2. 郵箱格式:
script type="text/javascript"> function isEmail(text) { var reg = /^([\w-.])+@([\w-])+((\.[\w-]{2,3}){1,2})$/; return reg.test(text); } var value2 = "Zhang.San@163.com"; document.write(value2 + " is Email:" + isEmail(value2)); /script>
3.將一個文本中的所有郵箱地址和在文本中的位置打印到頁面
script type="text/javascript"> function PrintEmail(text) { //匹配的模式 var reg = RegExp("([\\w-.])+@([\\w-])+((\.[\\w-]{2,3}){1,2})", "g"); var result; //保存結果 while ((result = reg.exec(text)) != null) { document.write(result[0] + "br/>" + result.index); document.write("br/>br/>"); } } var text = "張三 Zhang.San@163.com; 李四 Li_si@126.com;王五 WangWu@gmail.com.cn" ; PrintEmail(text); /script>
應用場景
數據驗證:
例如,可以檢查輸入的字符串,看其是否為電話號碼格式,或是否為郵箱格式。 這在網頁的表單輸入中經常用到。
查找子串:
可以查找文檔內( 或一個字符串內 ) 符合指定模式的子串。
替換文本:
可以使用正則表達式來識別文檔中的特定內容,完全刪除該部分內容或者用其他字符串來替換它。
使用工具:
如 Word 、 NotePad++ 、 EditPlus 等文字編輯器中的查找功能都支持正則表達式,用正則表達式你就可以實現更加多樣化的查找。還有像 VS 、 CodeBlock 、 Eclipse 、 Intellij Idea 等開發工具的 IDE 的查找替換功能也都支持正則表達式,用它你可以修改變量名,調整代碼格式,統計代碼行數等。
常用正則表達式總結
常用的正則表達式已經有很多人做了總結了,在網上能夠找到非常多,我就沒有再寫的必要了。下面貼出我覺得還不錯的一個總結。
此部分內容為轉載,來自: http://www.cnblogs.com/zxin/archive/2013/01/26/2877765.html
一、校驗數字的表達式
1 數字:^[0-9]*$
2 n位的數字:^\d{n}$
3 至少n位的數字:^\d{n,}$
4 m-n位的數字:^\d{m,n}$
5 零和非零開頭的數字:^(0|[1-9][0-9]*)$
6 非零開頭的最多帶兩位小數的數字:^([1-9][0-9]*)+(.[0-9]{1,2})?$
7 帶1-2位小數的正數或負數:^(\-)?\d+(\.\d{1,2})?$
8 正數、負數、和小數:^(\-|\+)?\d+(\.\d+)?$
9 有兩位小數的正實數:^[0-9]+(.[0-9]{2})?$
10 有1~3位小數的正實數:^[0-9]+(.[0-9]{1,3})?$
11 非零的正整數:^[1-9]\d*$ 或 ^([1-9][0-9]*){1,3}$ 或 ^\+?[1-9][0-9]*$
12 非零的負整數:^\-[1-9][]0-9"*$ 或 ^-[1-9]\d*$
13 非負整數:^\d+$ 或 ^[1-9]\d*|0$
14 非正整數:^-[1-9]\d*|0$ 或 ^((-\d+)|(0+))$
15 非負浮點數:^\d+(\.\d+)?$ 或 ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$
16 非正浮點數:^((-\d+(\.\d+)?)|(0+(\.0+)?))$ 或 ^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$
17 正浮點數:^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ 或 ^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$
18 負浮點數:^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ 或 ^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$
19 浮點數:^(-?\d+)(\.\d+)?$ 或 ^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$
二、校驗字符的表達式
1 漢字:^[\u4e00-\u9fa5]{0,}$
2 英文和數字:^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$
3 長度為3-20的所有字符:^.{3,20}$
4 由26個英文字母組成的字符串:^[A-Za-z]+$
5 由26個大寫英文字母組成的字符串:^[A-Z]+$
6 由26個小寫英文字母組成的字符串:^[a-z]+$
7 由數字和26個英文字母組成的字符串:^[A-Za-z0-9]+$
8 由數字、26個英文字母或者下劃線組成的字符串:^\w+$ 或 ^\w{3,20}$
9 中文、英文、數字包括下劃線:^[\u4E00-\u9FA5A-Za-z0-9_]+$
10 中文、英文、數字但不包括下劃線等符號:^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$
11 可以輸入含有^%',;=?$\"等字符:[^%',;=?$\x22]+
12 禁止輸入含有~的字符:[^~\x22]+
三、特殊需求表達式
1 Email地址:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
2 域名:[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?
3 InternetURL:[a-zA-z]+://[^\s]* 或 ^http://([\w-]+\.)+[\w-]+(/[\w-./?%=]*)?$
4 手機號碼:^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$
5 電話號碼("XXX-XXXXXXX"、"XXXX-XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX):^(\(\d{3,4}-)|\d{3.4}-)?\d{7,8}$
6 國內電話號碼(0511-4405222、021-87888822):\d{3}-\d{8}|\d{4}-\d{7}
7 身份證號(15位、18位數字):^\d{15}|\d{18}$
8 短身份證號碼(數字、字母x結尾):^([0-9]){7,18}(x|X)?$ 或 ^\d{8,18}|[0-9x]{8,18}|[0-9X]{8,18}?$
9 帳號是否合法(字母開頭,允許5-16字節,允許字母數字下劃線):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
10 密碼(以字母開頭,長度在6~18之間,只能包含字母、數字和下劃線):^[a-zA-Z]\w{5,17}$
11 強密碼(必須包含大小寫字母和數字的組合,不能使用特殊字符,長度在8-10之間):^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$
12 日期格式:^\d{4}-\d{1,2}-\d{1,2}
13 一年的12個月(01~09和1~12):^(0?[1-9]|1[0-2])$
14 一個月的31天(01~09和1~31):^((0?[1-9])|((1|2)[0-9])|30|31)$
15 錢的輸入格式:
16 1.有四種錢的表示形式我們可以接受:"10000.00" 和 "10,000.00", 和沒有 "分" 的 "10000" 和 "10,000":^[1-9][0-9]*$
17 2.這表示任意一個不以0開頭的數字,但是,這也意味著一個字符"0"不通過,所以我們采用下面的形式:^(0|[1-9][0-9]*)$
18 3.一個0或者一個不以0開頭的數字.我們還可以允許開頭有一個負號:^(0|-?[1-9][0-9]*)$
19 4.這表示一個0或者一個可能為負的開頭不為0的數字.讓用戶以0開頭好了.把負號的也去掉,因為錢總不能是負的吧.下面我們要加的是說明可能的小數部分:^[0-9]+(.[0-9]+)?$
20 5.必須說明的是,小數點后面至少應該有1位數,所以"10."是不通過的,但是 "10" 和 "10.2" 是通過的:^[0-9]+(.[0-9]{2})?$
21 6.這樣我們規定小數點后面必須有兩位,如果你認為太苛刻了,可以這樣:^[0-9]+(.[0-9]{1,2})?$
22 7.這樣就允許用戶只寫一位小數.下面我們該考慮數字中的逗號了,我們可以這樣:^[0-9]{1,3}(,[0-9]{3})*(.[0-9]{1,2})?$
23 8.1到3個數字,后面跟著任意個 逗號+3個數字,逗號成為可選,而不是必須:^([0-9]+|[0-9]{1,3}(,[0-9]{3})*)(.[0-9]{1,2})?$
24 備注:這就是最終結果了,別忘了"+"可以用"*"替代如果你覺得空字符串也可以接受的話(奇怪,為什么?)最后,別忘了在用函數時去掉去掉那個反斜杠,一般的錯誤都在這里
25 xml文件:^([a-zA-Z]+-?)+[a-zA-Z0-9]+\\.[x|X][m|M][l|L]$
26 中文字符的正則表達式:[\u4e00-\u9fa5]
27 雙字節字符:[^\x00-\xff] (包括漢字在內,可以用來計算字符串的長度(一個雙字節字符長度計2,ASCII字符計1))
28 空白行的正則表達式:\n\s*\r (可以用來刪除空白行)
29 HTML標記的正則表達式:(\S*?)[^>]*>.*?/\1>|.*? /> (網上流傳的版本太糟糕,上面這個也僅僅能部分,對于復雜的嵌套標記依舊無能為力)
30 首尾空白字符的正則表達式:^\s*|\s*$或(^\s*)|(\s*$) (可以用來刪除行首行尾的空白字符(包括空格、制表符、換頁符等等),非常有用的表達式)
31 騰訊QQ號:[1-9][0-9]{4,} (騰訊QQ號從10000開始)
32 中國郵政編碼:[1-9]\d{5}(?!\d) (中國郵政編碼為6位數字)
33 IP地址:\d+\.\d+\.\d+\.\d+ (提取IP地址時有用)
34 IP地址:((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)) (由@飛龍三少 提供,感謝共享)
寫在后面
正則表達式是一個非常強大而又非常常用的一個編程技術,我以上這片文章也只是拋磚引玉,講述了其中最常用的一部分。因為其內容實在太龐大,如果要詳細描述,每一種編程語言的正則表達式都可以單獨成一本書。
如果您有什么疑惑和想法,請在評論處給予反饋,您的反饋就是最好的測評師!由于本人技術和能力有限,如果本博文有錯誤或不足之處,敬請諒解并給出您寶貴的建議!