最全正規表示式總結:驗證QQ號、手機號、Email、中文、郵編、身份證、IP地址等

小飛鶴發表於2017-07-14

什麼是 RegExp?

  • RegExp 是正規表示式(Regular expression)的縮寫,作用是對字串執行模式匹配。

  • 通常用於格式驗證、正則替換、查詢子串等

  • 各種程式語言的正規表示式基本相同,不同的語言可能會有一些細小的差別

RegExp 語法

1
2
3
4
5
// 直接例項化
var reg = new RegExp(pattern [, flags]);
// 隱式建立(推薦)
var reg = /pattern/flags;

引數 pattern 是一個字串,指定了正規表示式的模式或其他正規表示式。

引數 [, flags] 是一個可選的字串,包含屬性 “g”(global )、”i” (ignoreCase)和 “m”(multiline)。

ECMAScript 標準化之前,不支援 m 屬性。如果 pattern 是正規表示式,而不是字串,則必須省略該引數。

概念:子表示式

在正規表示式中,使用括號括起來的內容是一個子表示式,子表示式匹配到的內容會被系統捕獲至緩衝區,使用\n(n:數字)來反向引用系統的第n號緩衝區的內容。

場景:後面的內容要求與前面的一致,可以使用子表示式

1
2
3
4
5
// 查詢連續相同的四個數字
var str = "1212ab45677778cd";
var reg = /(\d)\1\1\1/gi;
console.log(str.match(reg));
// OUTPUT:7777

概念:方括號(字元簇)

1
2
3
4
var str = "Is this all there is?";
var patt1 = /[a-h]/g;
document.write(str.match(patt1));
// OUTPUT:h,a,h,e,e
方括號 作用
[abc] 查詢方括號之間的任何字元。
[^abc] 查詢任何不在方括號之間的字元。
[0-9] 查詢任何從 0 至 9 的數字。同 \d
[a-z] 查詢任何從小寫 a 到小寫 z 的字元。
[A-Z] 查詢任何從大寫 A 到大寫 Z 的字元。
[A-z] 查詢任何從大寫 A 到小寫 z 的字元。
[0-9a-zA-Z] 查詢0-9,a-z,A-Z

概念:元字元

元字元(Metacharacter)是擁有特殊含義的字元:
元字元 | 作用
—|—
\ | 轉義符 (、)、/、\
| | 選擇匹配符,可以匹配多個規則
. | 查詢單個字元,除了換行和行結束符。
\w | 查詢單詞字元。字元 ( 字母 ,數字,下劃線_ )
\W | 查詢非單詞字元。
\d | 查詢數字。
\D | 查詢非數字字元。
\s | 查詢空白字元。空格
\S | 查詢非空白字元。
\b | 匹配單詞邊界。
\B | 匹配非單詞邊界。
\0 | 查詢 NUL 字元。
\n | 查詢換行符。
\f | 查詢換頁符。
\r | 查詢回車符。
\t | 查詢製表符。
\v | 查詢垂直製表符。
\xxx | 查詢以八進位制數 xxx 規定的字元。
\xdd | 查詢以十六進位制數 dd 規定的字元。
\uxxxx | 查詢以十六進位制數 xxxx 規定的 Unicode 字元。

概念:量詞

量詞 作用
n+ 匹配任何包含至少一個 n 的字串。同 {1,}
n* 匹配任何包含零個或多個 n 的字串。同 {0,}
n? 匹配任何包含零個或一個 n 的字串。同 {0,1}
n{X} 匹配包含 X 個 n 的序列的字串。
n{X,Y} 匹配包含 X 至 Y 個 n 的序列的字串。
n{X,} 匹配包含至少 X 個 n 的序列的字串。
n$ 匹配任何結尾為 n 的字串。
^n 匹配任何開頭為 n 的字串。注意 /[^a] / 和 /^ [a]/是不一樣的,前者是排除的,後者是代表首位。
(?=n) 匹配任何其後緊接指定字串 n 的字串。正向預查
(?!n) 匹配任何其後沒有緊接指定字串 n 的字串。反向預查

RegExp 物件方法

test()

test() 方法檢索字串中是否存在指定的值。返回值是 true 或 false。

1
2
3
4
5
6
7
var patt1 = new RegExp('e');
console.log(patt1.test('some text'));
// OUTPUT:true
var patt2 = new RegExp('ee');
console.log(patt2.test('some text'));
// OUTPUT:false
1
2
3
4
5
6
7
8
9
10
11
// 判斷是不是QQ號
// 1 首位不能是0 ^[1-9]
// 2 必須是 [5, 11] 位的數字 \d{4, 9}
var str = '80583600';
var regexp = /^[1-9][0-9]{4,10}$/gim;
if (regexp.test(str)) {
alert('is');
} else {
alert('no');
}

exec()

exec() 方法檢索字串中的指定值。返回值是被找到的值。如果沒有發現匹配,則返回 null。

1
2
3
4
5
6
7
var patt1 = new RegExp('e');
console.log(patt1.exec('some text'));
// OUTPUT:e
var patt2 = new RegExp('ee');
console.log(patt2.exec('some text'));
// OUTPUT:null

compile()

compile() 既可以改變檢索模式,也可以新增或刪除第二個引數。

1
2
3
4
5
6
var patt1=new RegExp("e");
document.write(patt1.test("The best things in life are free")); // true
// 改變了檢索模式
patt1.compile("eee");
document.write(patt1.test("The best things in life are free")); // false

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

search 檢索與正規表示式相匹配的值。

1
2
3
var str = "Visit W3School!"
console.log(str.search(/W3School/))
// OUTPUT:6

match 找到一個或多個正規表示式的匹配。

1
2
3
var str="1 plus 2 equal 3"
console.log(str.match(/\d+/g))
// OUTPUT:1,2,3

replace 替換與正規表示式匹配的子串。

1
2
3
var str = "Visit Microsoft!"
console.log(str.replace(/Microsoft/, "W3School"));
// OUTPUT:Visit W3School!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// 找重複項最多的字元個數
var str = 'g21ss4aeba_ersb43sgnnsssstht6sss60snnsj8resw0_ss';
// split : 將字串轉化為陣列
// sort : 對陣列排序,ASCII
// join : 將陣列轉化為字串
var str_new = str.split('').sort().join('');
document.write(str + '<br>');
document.write(str.split('') + '<br>');
document.write(str.split('').sort() + '<br>');
document.write(str.split('').sort().join('') + '<br>');
// 匹配字元,且重複這個字元,重複次數至少一次。
var regexp = /(\w)\1+/g;
var index = 0;
var value = '';
str_new.replace(regexp, function($0, $1) {
// document.write($0);
// document.write($1);
if (index < $0.length) {
index = $0.length;
value = $1;
}
});
document.write('重複項最多的字元是:' + value + ',個數是:' + index);
// OUTPUT:
// 0012344668__aabbeeegghjnnnnrrssssssssssssssssttw
// 重複項最多的字元是:s,個數是:16

split 把字串分割為字串陣列。

1
2
3
var str = "How are you doing today?"
document.write(str.split(/\s+/));
// OUTPUT:How,are,you,doing,today?

經驗:

  1. 檢驗格式(郵箱格式、IP格式)是否正確,用test()
  2. 抓取星期(如所有手機號),用exec()、match()
  3. 替換敏感詞彙,用replace()

常見的 正規表示式 校驗

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// 常見的 正規表示式 校驗
// QQ號、手機號、Email、是否是數字、去掉前後空格、是否存在中文、郵編、身份證、URL、日期格式、IP
var myRegExp = {
// 檢查字串是否為合法QQ號碼
isQQ: function(str) {
// 1 首位不能是0 ^[1-9]
// 2 必須是 [5, 11] 位的數字 \d{4, 9}
var reg = /^[1-9][0-9]{4,9}$/gim;
if (reg.test(str)) {
console.log('QQ號碼格式輸入正確');
return true;
} else {
console.log('請輸入正確格式的QQ號碼');
return false;
}
},
// 檢查字串是否為合法手機號碼
isPhone: function(str) {
var reg = /^(0|86|17951)?(13[0-9]|15[012356789]|18[0-9]|14[57]|17[678])[0-9]{8}$/;
if (reg.test(str)) {
console.log('手機號碼格式輸入正確');
return true;
} else {
console.log('請輸入正確格式的手機號碼');
return false;
}
},
// 檢查字串是否為合法Email地址
isEmail: function(str) {
var reg = /^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/;
// var reg = /\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/;
if (reg.test(str)) {
console.log('Email格式輸入正確');
return true;
} else {
console.log('請輸入正確格式的Email');
return false;
}
},
// 檢查字串是否是數字
isNumber: function(str) {
var reg = /^\d+$/;
if (reg.test(str)) {
console.log(str + '是數字');
return true;
} else {
console.log(str + '不是數字');
return false;
}
},
// 去掉前後空格
trim: function(str) {
var reg = /^\s+|\s+$/g;
return str.replace(reg, '');
},
// 檢查字串是否存在中文
isChinese: function(str) {
var reg = /[\u4e00-\u9fa5]/gm;
if (reg.test(str)) {
console.log(str + ' 中存在中文');
return true;
} else {
console.log(str + ' 中不存在中文');
return false;
}
},
// 檢查字串是否為合法郵政編碼
isPostcode: function(str) {
// 起始數字不能為0,然後是5個數字 [1-9]\d{5}
var reg = /^[1-9]\d{5}$/g;
// var reg = /^[1-9]\d{5}(?!\d)$/;
if (reg.test(str)) {
console.log(str + ' 是合法的郵編格式');
return true;
} else {
console.log(str + ' 是不合法的郵編格式');
return false;
}
},
// 檢查字串是否為合法身份證號碼
isIDcard: function(str) {
var reg = /^(^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$)|(^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])((\d{4})|\d{3}[Xx])$)$/;
if (reg.test(str)) {
console.log(str + ' 是合法的身份證號碼');
return true;
} else {
console.log(str + ' 是不合法的身份證號碼');
return false;
}
},
// 檢查字串是否為合法URL
isURL: function(str) {
var reg = /^https?:\/\/(([a-zA-Z0-9_-])+(\.)?)*(:\d+)?(\/((\.)?(\?)?=?&?[a-zA-Z0-9_-](\?)?)*)*$/i;
if (reg.test(str)) {
console.log(str + ' 是合法的URL');
return true;
} else {
console.log(str + ' 是不合法的URL');
return false;
}
},
// 檢查字串是否為合法日期格式 yyyy-mm-dd
isDate: function(str) {
var reg = /^[1-2][0-9][0-9][0-9]-[0-1]{0,1}[0-9]-[0-3]{0,1}[0-9]$/;
if (reg.test(str)) {
console.log(str + ' 是合法的日期格式');
return true;
} else {
console.log(str + ' 是不合法的日期格式,yyyy-mm-dd');
return false;
}
},
// 檢查字串是否為合法IP地址
isIP: function(str) {
// 1.1.1.1 四段 [0 , 255]
// 第一段不能為0
// 每個段不能以0開頭
//
// 本機IP: 58.50.120.18 湖北省荊州市 電信
var reg = /^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$/gi;
if (reg.test(str)) {
console.log(str + ' 是合法的IP地址');
return true;
} else {
console.log(str + ' 是不合法的IP地址');
return false;
}
}
}
// 測試
// console.log(myRegExp.isQQ('80583600'));
// console.log(myRegExp.isPhone('17607160722'));
// console.log(myRegExp.isEmail('80583600@qq.com'));
// console.log(myRegExp.isNumber('100a'));
// console.log(myRegExp.trim(' 100 '));
// console.log(myRegExp.isChinese('baixiaoming'));
// console.log(myRegExp.isChinese('小明'));
// console.log(myRegExp.isPostcode('412345'));
// console.log(myRegExp.isIDcard('42091119940927001X'));
// console.log(myRegExp.isURL('https://www.baidu.com/'));
// console.log(myRegExp.isDate('2017-4-4'));
// console.log(myRegExp.isIP('1.0.0.0'));

一、校驗數字的表示式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
數字:^[0-9]*$
n位的數字:^\d{n}$
至少n位的數字:^\d{n,}$
m-n位的數字:^\d{m,n}$
零和非零開頭的數字:^(0|[1-9][0-9]*)$
非零開頭的最多帶兩位小數的數字:^([1-9][0-9]*)+(.[0-9]{1,2})?$
帶1-2位小數的正數或負數:^(\-)?\d+(\.\d{1,2})?$
正數、負數、和小數:^(\-|\+)?\d+(\.\d+)?$
有兩位小數的正實數:^[0-9]+(.[0-9]{2})?$
有1~3位小數的正實數:^[0-9]+(.[0-9]{1,3})?$
非零的正整數:^[1-9]\d*$ 或 ^([1-9][0-9]*){1,3}$ 或 ^\+?[1-9][0-9]*$
非零的負整數:^\-[1-9][]0-9"*$ 或 ^-[1-9]\d*$
非負整數:^\d+$ 或 ^[1-9]\d*|0$
非正整數:^-[1-9]\d*|0$ 或 ^((-\d+)|(0+))$
非負浮點數:^\d+(\.\d+)?$ 或 ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$
非正浮點數:^((-\d+(\.\d+)?)|(0+(\.0+)?))$ 或 ^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$
正浮點數:^[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]*))$
負浮點數:^-([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]*)))$
浮點數:^(-?\d+)(\.\d+)?$ 或 ^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$

二、校驗字元的表示式

1
2
3
4
5
6
7
8
9
10
11
漢字:^[\u4e00-\u9fa5]{0,}$
英文和數字:^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$
長度為3-20的所有字元:^.{3,20}$
由26個英文字母組成的字串:^[A-Za-z]+$
由26個大寫英文字母組成的字串:^[A-Z]+$
由26個小寫英文字母組成的字串:^[a-z]+$
由數字和26個英文字母組成的字串:^[A-Za-z0-9]+$
由數字、26個英文字母或者下劃線組成的字串:^\w+$ 或 ^\w{3,20}$
中文、英文、數字包括下劃線:^[\u4E00-\u9FA5A-Za-z0-9_]+$
可以輸入含有^%&',;=?$\"等字元:[^%&',;=?$\x22]+
禁止輸入含有~的字元:[^~\x22]+

三、特殊需求表示式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Email地址:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
域名:[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?
InternetURL:[a-zA-z]+://[^\s]* 或 ^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$
手機號碼:^(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}$
電話號碼("XXX-XXXXXXX"、"XXXX-XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX):^(\(\d{3,4}-)|\d{3.4}-)?\d{7,8}$
國內電話號碼(0511-4405222、021-87888822):\d{3}-\d{8}|\d{4}-\d{7}
身份證號(15位、18位數字):^\d{15}|\d{18}$
短身份證號碼(數字、字母x結尾):^([0-9]){7,18}(x|X)?$ 或 ^\d{8,18}|[0-9x]{8,18}|[0-9X]{8,18}?$
帳號是否合法(字母開頭,允許5-16位元組,允許字母數字下劃線):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
密碼(以字母開頭,長度在6~18之間,只能包含字母、數字和下劃線):^[a-zA-Z]\w{5,17}$
強密碼(必須包含大小寫字母和數字的組合,不能使用特殊字元,長度在8-10之間):^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$
日期格式:^\d{4}-\d{1,2}-\d{1,2}
一年的12個月(01~09和1~12):^(0?[1-9]|1[0-2])$
一個月的31天(01~09和1~31):^((0?[1-9])|((1|2)[0-9])|30|31)$
xml檔案:^([a-zA-Z]+-?)+[a-zA-Z0-9]+\\.[x|X][m|M][l|L]$
中文字元的正規表示式:[\u4e00-\u9fa5]
雙位元組字元:[^\x00-\xff] (包括漢字在內,可以用來計算字串的長度(一個雙位元組字元長度計2,ASCII字元計1))
空白行的正規表示式:\n\s*\r (可以用來刪除空白行)
HTML標記的正規表示式:<(\S*?)[^>]*>.*?</\1>|<.*? /> (網上流傳的版本太糟糕,上面這個也僅僅能部分,對於複雜的巢狀標記依舊無能為力)
首尾空白字元的正規表示式:^\s*|\s*$或(^\s*)|(\s*$) (可以用來刪除行首行尾的空白字元(包括空格、製表符、換頁符等等),非常有用的表示式)
騰訊QQ號:[1-9][0-9]{4,} (騰訊QQ號從10000開始)
中國郵政編碼:[1-9]\d{5}(?!\d) (中國郵政編碼為6位數字)
IP地址:\d+\.\d+\.\d+\.\d+ (提取IP地址時有用)
IP地址:((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))

錢的輸入格式:

1
2
3
4
5
6
7
8
9
1.有四種錢的表示形式我們可以接受:"10000.00" 和 "10,000.00", 和沒有 "分" 的 "10000" 和 "10,000":^[1-9][0-9]*$
2.這表示任意一個不以0開頭的數字,但是,這也意味著一個字元"0"不通過,所以我們採用下面的形式:^(0|[1-9][0-9]*)$
3.一個0或者一個不以0開頭的數字.我們還可以允許開頭有一個負號:^(0|-?[1-9][0-9]*)$
4.這表示一個0或者一個可能為負的開頭不為0的數字.讓使用者以0開頭好了.把負號的也去掉,因為錢總不能是負的吧.下面我們要加的是說明可能的小數部分:^[0-9]+(.[0-9]+)?$
5.必須說明的是,小數點後面至少應該有1位數,所以"10."是不通過的,但是 "10" 和 "10.2" 是通過的:^[0-9]+(.[0-9]{2})?$
6.這樣我們規定小數點後面必須有兩位,如果你認為太苛刻了,可以這樣:^[0-9]+(.[0-9]{1,2})?$
7.這樣就允許使用者只寫一位小數.下面我們該考慮數字中的逗號了,我們可以這樣:^[0-9]{1,3}(,[0-9]{3})*(.[0-9]{1,2})?$
8.1到3個數字,後面跟著任意個 逗號+3個數字,逗號成為可選,而不是必須:^([0-9]+|[0-9]{1,3}(,[0-9]{3})*)(.[0-9]{1,2})?$
備註:這就是最終結果了,別忘了"+"可以用"*"替代如果你覺得空字串也可以接受的話(奇怪,為什麼?)最後,別忘了在用函式時去掉去掉那個反斜槓,一般的錯誤都在這裡

相關文章