什么是正則表達式
正則表達式(regular expression)描述了一種字符串匹配的模式(pattern),可以用來檢查一個串是否含有某種子串、將匹配的子串替換或者從某個串中取出符合某個條件的子串等。
簡單的說,正則表達式是一些用來匹配和處理文本的字符串.利用正則表達式我們可以查找特定的信息,或者替換掉文本中的特定信息.
并且正則表達式搜索的能力和替換文本的能力極為強大,而且其也比較容易學(xué)習(xí)和掌握.
那么正則表達式是什么樣子的,有什么規(guī)則,又該如何使用呢?如下面這樣的語句:
注:所有舉例都是選用javascript編程語言中的正則表達式,所有可能會與其他編程的正則表達式有些出入
/b[Cc][Aa]/
這就是一個正則表達式,它可以匹配bca,bCa,bcA,bCA這些字符串.所以我想現(xiàn)在你應(yīng)該對于正則表達式有些概念了.
接下來我們來介紹一些正則表達式的規(guī)則和語法.

正則表達語法結(jié)構(gòu)
正則表達式的語法結(jié)構(gòu)如下:
/正則表達式主體/修飾符(可選)
我們來舉一個實例來分析一下
/runoob/i
/runoob/i 是一個正則表達式。
runoob 是一個正則表達式主體 (用于檢索)。
i 是一個修飾符 (搜索不區(qū)分大小寫)。
所以該正則表達式可以匹配Runoob,rUnoob等不區(qū)分大小寫的內(nèi)容符合runoob的字符串集.
正則表達式修飾符
修飾符是影響整個正則規(guī)則的特殊符號,會對匹配結(jié)果和部分內(nèi)置函數(shù)行為產(chǎn)生不同的效果,JavaScript正則表達式中,包含以下三個修飾符:
| 修飾符 | 描述 |
|---|---|
| i | 執(zhí)行對大小寫不敏感的匹配 |
| g | 執(zhí)行全局匹配(查找所有匹配而非在找到第一個匹配后停止 |
| m | 執(zhí)行多行匹配 |
匹配單個任意字符
在正則表達式里,我們用.符號來匹配任何一個單個的字符. 例:
var str1 = 'ab'
var str2 = 'a.b'
var str3 = 'acb'
var str4 = 'ac.b'
var reg = /a.b/
console.log(reg.test(str1)) //-> false
console.log(reg.test(str2)) //-> ture
console.log(reg.test(str3)) //-> true
console.log(reg.test(str4)) //-> false
匹配特殊字符
從上個例子中,我們了解到.字符在正則表達式里有著特殊的含義. 如果我們的模式里需要一個.那該怎么辦?
這時,我們可以在.加上\(反斜杠)字符來對它進行轉(zhuǎn)義,使得.表示的是它自身的文本內(nèi)容,而不是它在正則表達式中的特殊含義.例:
var str1 = 'baidu.com'
var str2 = 'baidu@com'
var reg1 = /baidu\.com/
var reg2 = /baidu.com/
console.log(reg1.test(str1)) // -> true
console.log(reg1.test(str2)) // -> false 分析: 字符`@`與字符'.'不匹配
console.log(reg2.test(str1)) // -> true 分析: `.`可以匹配任意一個字符, 包括'.'字符本身.
console.log(reg2.test(str2)) // -> true
同.一樣,/也是一個特殊字符, 如果你想要匹配/內(nèi)容本身,應(yīng)該用//來表示.除此,正則表達式中還有很多特殊字符,我們會在下面慢慢介紹.
匹配字符區(qū)間(一組字符)中的某一個
-
[]的使用
在正則表達式中,我們可以使用元字符[和]來定義一個字符集合. 這兩個元字符之間的所有字符都是該集合的組成部分.字符集合的匹配結(jié)果是能夠與該集合里的任意一個成員相匹配的文本.例:
// 寫一個正則表達式可以匹配'ca.xls'和'na.xls'.
var reg = /[cn]a.xls/
// 列舉幾個字符串來驗證正則
var s1 = 'ca.xls'
var s2 = 'na.xls'
var s3 = 'sa.xls'
console.log(reg.test(s1)) // -> true
console.log(reg.test(s2)) // -> true
console.log(reg.test(s3)) // -> false
- 數(shù)字字母區(qū)間
/[0123456789]/
上述正則表達式可以用來匹配0到9這個10個數(shù)字中任意一個.
- 字母字符區(qū)間
/[abcdefg]/
上述正則表達式可以用來匹配a-g字符中任意一個字符.
- 簡化寫法
上述正則表達式雖然可以表達一些字符區(qū)間,但是其寫法有些繁瑣.為此,正則表達式中提供了一些簡化的寫法:
| 區(qū)間 | 說明 |
|---|---|
| [0-9] | 匹配0到9之間的數(shù)字. |
| [A-Z] | 匹配A到Z之間的所有大寫字母. |
| [a-z] | 匹配a到z之間的所有小寫字母. |
| [A-F] | 匹配A到F之間的所有大寫字母. |
| [a-f] | 匹配a到f之間的所有小寫字母. |
| [A-z] | 匹配ASCII字符A到ASCII字符z的所有字母.(不過不常用,因為其中還包含[和^等排列在Z和a之間的字符) |
提示:在定義一個字符區(qū)間的時候,一定要避免讓這個區(qū)間的尾字符小于它的首字符. 例如 [3-1]這種區(qū)間就是沒有意義的,而且往往會讓整個模式失效
- 取非匹配
字符集合通常用來指定一組必須匹配其中之一的字符. 但是有時候我們需要翻過來做,給出一組不需要得到的字符.這時,我們可以用元字符
^來對一個字符集合進行取非匹配. 例:
var reg = /[^0-9]/
var str1 = '1'
var str2 = 'a'
console.log(reg.test(str1)) // -> false
console.log(reg.test(str2)) // -> true
這個正則表達式匹配的是任何不是數(shù)字的字符.
提示: 我們可以把取非理解成數(shù)學(xué)中的獲取補集
類元字符
字符集合(匹配多個字符中的某一個)是最常見的匹配的形式,而一些常用的字符集合可以用特殊元字符來代替可以用特殊元字符來代替.這些元字符匹配的是某一類別的字符(術(shù)語稱之為'類元字符').類元字符并不是必不可少的東西,但用它們構(gòu)造出來的正則表達式簡明易懂,在實踐中很有用.
- 匹配數(shù)字(與非數(shù)字)
之前我們介紹過,[0-9]是[0123456789]的簡寫形式,它可以用來匹配任何一個數(shù)字.不過你若是想匹配的除數(shù)字以外的其他東西,那么對這個集合取非寫成[^0-9]便可以了.下面我們列出了用來匹配數(shù)字和非數(shù)字的類元字符.
| 元字符 | 說明 |
|---|---|
| \d | 任何一個數(shù)字字符(等價于[ 0-9 ]) |
| \D | 任何一個非數(shù)字字符(等價于[ ^ 0-9 ] ) |
例:
var reg = /\d/
var str1 = '7'
var str2 = 'a'
console.log(reg.test(str1)) // ->true
console.log(reg.test(str2)) // -> false
console.log(/\D/.test(str2)) // -> true
- 匹配字母和數(shù)字
字母和數(shù)字---A到Z(不區(qū)分大小寫),數(shù)字0到9,再加上下劃線字符
_是另一種比較常用的字符集合;這些字符 常見于各種名字里(如目錄名,變量名等等). 其類元字符如下:
| 元字符 | 說明 |
|---|---|
| \w | 任何一個字母數(shù)字字符(大小寫均可)或下劃線字符(等價于[a-zA-Z0-9_]) |
| \W | 任何一個非字母數(shù)字字符(大小寫均可)或下劃線字符(等價于[^ a-zA-Z0-9_]) |
個人認為\w中的w可能word這個單詞的簡寫,所以我跟喜歡稱\w為單詞字符.
例:
var reg = /\w+/
var str1 = 'abc123_'
var str2 = '-;~@'
console.log(reg.test(str1)) // ->true
console.log(reg.test(str2)) // -> false
console.log(/\W+/.test(str2)) // -> true
匹配空白字符
在介紹如何匹配空白字符,我們先來說一些小常識.
-
回車與換行
- 回車的轉(zhuǎn)義字符是
/r, 回車是光標(biāo)回到當(dāng)前行的開始位置. - 換行的轉(zhuǎn)義字符是
/n, 換行是光標(biāo)轉(zhuǎn)到當(dāng)前位置的下一行相同的位置.
- 回車的轉(zhuǎn)義字符是
因此,在DOS和WINDOWS系統(tǒng)上,回車和換行必須連用,從而實現(xiàn)文 本字符的換行并回到下一行的起始位置.包括HTTP也使用CRLF來表示 每一行的結(jié)束.
而在UNIX,LINUX中,只有換行碼而不需要回車碼,系統(tǒng)默認換行就是回車加換行。
但是,在MAC上,Mac OS 9 以及之前的系統(tǒng)的換行符是CR即\r ,從 Mac OS X (后來改名為“OS X”)開始的換行符是 LF即\n,和Unix/Linux統(tǒng)一了。
- 如何表示一個空白行
在Windows中用\r\n\r\n來代表一個空白行.而在Linux中用\n\n來代表一個空白行.
我們可以用正則表達式[\r]?\n[\r]?\n來匹配不同系統(tǒng)中的一個空白行.
關(guān)于空白行的匹配,我想你也許會有這樣一個疑問: 遇到\r\n\n或者\n\r\n\這兩種情況,該如何? 如果遇見這兩種情況的話的確會被上述正則表達式所匹配.但是一般情況下,這兩種情況極為少見(通常只有人為的拼接換行符時才會出現(xiàn)這種情況).所以你可以安心使用,如果你還覺得不放心的話,可以用/[(\r\n\r\n)(\n\n)]/來匹配空白行.
-
空格和空白字符
其實空格只是字符中的一種,它并不是轉(zhuǎn)義字符.
' '這便是空格字符的表示方法.
下面是一個用正則來驗證空格字符的:var str = 'hello world' var str2 = 'helloworld' var reg = / / console.log(reg.test(str)) // -> true console.log(reg.test(str2)) // -> false但是在正則表達式中可以用
\s來匹配空白字符.需要注意的是空白字符并不等同于空格字符,或者說空格字符是空白字符的一個成員.空白字符有:字符 說明 \n 換行字符 \f 換頁符 \r 回車符號 \t 制表符 \v 垂直制表符 " " 空格(js中的特有的)
因此上述代碼也可以改為如下:
```js
var str = 'hello world'
var str2 = 'helloworld'
var reg = /\s/
console.log('str',reg.test(str),'str2',reg.test(str2))
// str true str2 false
```
匹配十六進制和八進制
- 十六進制
我們可以用前綴\x來匹配十六進制值. 例如\x0A對ASCII中的序號為10的符號(換行符),其效果等價于\n.
- 八進?制
我們用前綴\0來匹配八進制值.例如\011對應(yīng)于ASCII中的序號為9的符號(制表符),其效果等價于\t.
重復(fù)匹配
- 匹配一個或多個字符
我們可以給字符(或者字符集合)加上一個+作為后綴,來匹配一個或多個(至少一個,不匹配0個字符的情況)字符.
var reg = /ba+/
// 匹配 "baaa","ba", 但不匹配"b".
var reg = /[0-9]+/
//匹配任意數(shù)字串的組合.
var reg = /[0-9+]/
/*
這樣寫?雖然是合法正則式,但是不能匹配一個或者多個數(shù)字.
它代表的是 [0123456789+]這個集合中的任意一個字符.
*/
- 匹配零個或多個字符
我們可以給字符(或者字符集合)加上一個*作為后綴,來匹配零個或多個字符. 例:
var reg = /ba*/
var str1 = 'baaaa'
var str2 = 'b'
console.log(reg.test(str1)) // -> ture
console.log(reg.test(str2)) // -> ture
- 匹配零個或者一個字符
我們可以給字符(或者字符集合)加上一個?作為后綴,來匹配零個或多個字符.例:
// 匹配http或者https,可以用如下正則表達式
var reg = /http[s]?/ // => http或者https
// 匹配不同系統(tǒng)中的空白行
reg = /[\r]?\n[\r]?\n/ //=> \r\n\r\n 或者\n\n
-
匹配的重復(fù)次數(shù)
我們可用用
{}符號來為重復(fù)匹配設(shè)定重復(fù)次數(shù).- 為重復(fù)匹配次數(shù)設(shè)定一個精確的值
var reg = /#[0-9A-Fa-f]{6}/ // 可以用來匹配任意一個RGB值.
reg.test('#486D3A') // true
reg.test('#3F3F46') // true
reg.test('#3F3F4')) //false
- 為重復(fù)匹配次數(shù)設(shè)定一個區(qū)間
{}還可以用來為為重復(fù)匹配次數(shù)設(shè)定一個區(qū)間.如{2,4}這樣的形式,代表的含義是最少重復(fù)兩次,最多重復(fù)4次.
var reg = /\d{2,4}/
reg.test('1') // -> false
reg.test('12') // -> true
reg.test('1234') // -> true
{3,}表示至少重復(fù)3次. 如:
var reg=/\d{3,}/
reg.test('1') // -> false
reg.test('1234') // -> true
防止過度匹配
我們利用正則表達式來獲取文本中的a標(biāo)簽,如下例:
var str = ' this offer is not available to customers living in <a>AK</a> and <a>HI</a>'
var reg = /<a>.*<\/a>/g
str.match(reg) // 匹配結(jié)果: <a>AK</a> and <a>HI</a>
我們發(fā)現(xiàn)雖然沒有漏掉我們想要匹配的文本,但是并不是我們預(yù)期的結(jié)果, 我們想要的結(jié)果是分別返回兩個標(biāo)簽,而不是一個包含兩個標(biāo)簽的文本.
這是因為,*和+都是所謂的貪婪型元字符,它們進行匹配時的行為模式是多多益善而不是適可而止的.它會盡可能的從一段文本的開頭一直匹配到這段文本的結(jié)尾,而不是從這段文本的開頭到到第一個匹配時為止.
那么問題來了,如果我們不需要這種貪婪行為?,該怎么辦呢?答案便是用這些元字符的懶惰版本.即匹配盡可能少的字符.下面是幾個常用的貪婪型元字符和它的懶惰版本:
| 貪婪型元字符 | 懶惰型元字符 |
|---|---|
| * | *? |
| + | +? |
| {n,} | {n,}? |
現(xiàn)在我們修改上一次的代碼,使它達到我們的預(yù)期.
var str = ' this offer is not available to customers living in <a>AK</a> and <a>HI</a>'
var reg = /<a>.*?<\/a>/g
str.match(reg) // 匹配結(jié)果: ["<a>AK</a>", "<a>HI</a>"]
我們應(yīng)根據(jù)具體情況來選用'貪婪型'或'懶惰型'元字符.
位置匹配
在某些場合中,我們需要對某段文本的特定位置進行匹配,這是就需要使用位置匹配來解決了.
提示:位置匹配符,只匹配位置而不匹配內(nèi)容.這點極為重要,需要牢記
- 單詞邊界
我們用限定符\b(boundary)來指定單詞的邊界,\b可以用來匹配一個單詞的開頭或結(jié)尾.
\b匹配的是這樣一個位置: 這個位置位于一個能夠用來構(gòu)成單詞的字符(字母,數(shù)字以及下劃線.即\w)和一個不能用來夠成單詞的字符(即\W)之間.
我們可以用|來模擬邊界符,為字符串"the captain wore his cap and cape proundly"
結(jié)果如下:
|the| |captain| |wore| |his| |cap| |and| |cape| |proundly|
如果到這里你對與這個單詞邊界符\b還有些疑惑. 我們可以再舉個例子:
字符串: "baidu.com"
我們知道上述字符串中的.并不在\w中.所以我們認為它是一個非單詞字符.而.兩邊分別是字母u和字母c,它們都屬于\w,都是單詞字符.
如上述的關(guān)于單詞邊界的定義解釋一樣,單詞邊界是一個能夠用來構(gòu)成單詞的字符(字母,數(shù)字以及下劃線.即\w)和一個不能用來夠成單詞的字符(即\W)之間的位置.我們?yōu)樽址由线吔?如下:
|baidu|.|com
即單詞字符與非單詞字符之間的位置就是單詞邊界.
接下來我們來看看一個使用\b的例子:
var str1 = 'and cap proundly '
var str2 = 'and cape proundly '
var reg= /\bcap\b/
// 匹配字符串是否有"cap"這個單詞
console.log(reg.test(str1)) // -> true
console.log(reg.test(str2)) // -> false
- 字符串邊界
字符串邊界可以用來進行與字符串有關(guān)的?位置匹配(字符串的開頭,結(jié)尾,等等.)
- 用
^匹配字符串的開頭
我們用^來匹配一個字符串的開頭位置.用法如下:
var str1 = 'I will persist until I succeed.'
var str2 = 'You will persist until I succeed.'
var reg = /^I.*?/
reg.test(str1) // true
reg.test(str2) //false
^是幾個有著多種用途的元字符之一,只有當(dāng)它出現(xiàn)在一個字符集合里并且緊跟[之后,才能表現(xiàn)出"求非"的作用.如果是在一個字符集合外面并且位于一個模式的開頭,^將匹配一個字符?串的開頭.
- 用
$匹配字符串的結(jié)尾
同^的使用方法類似,我們用$來匹配字符串的結(jié)尾.用法如下:
var str1 = 'I will persist until I succeed'
var str2 = 'I will persist until I have success'
var reg = /s$/
reg.test(str1) // -> false
reg.test(str2) // -> true
接下來,我來說一種特殊的情況,就是當(dāng)^和$同時用于一個模式的時候.例:
var str1 = 'I will persist until I succeed'
var str2 ='I will'
var reg = /^I.*will$/
console.log( reg.test(str1)); // -> false
console.log( reg.test(str2)); // -> true
我們可以看出當(dāng)^和$同時用于一個模式的時候, 其匹配的只是模式本身(即使字符串中含有與模式匹配的文本也不可以). 對此,我只能表示ㄟ( ▔, ▔ )ㄏ.

子表達式
子表達式是一個更大的表達式的一部分;把一個表達式劃分為一系列子表達式的目的是為了把那些子表達式當(dāng)做一個獨立元素來使用.子表達式必須用
()括起來.
我們可以來看一個例子,用正則表達式來查找IP地址.IP地址的格式是以英文句號分割的四組數(shù)字,例如12.159.46.200.我們可以把它劃分為兩部分,一部分是形如xxx.的模式(IP地址的前3組便是這種模式),另一個部分是xxx的模式(IP地址的最后一組數(shù)字).
var str = 'my ip is 12.159.46.200 ok.';
var reg = /(\d{1,3}\.){3}\d{1,3}/g
console.log(str.match(reg)) // ->['12.159.46.200']
回溯引用:前后一致匹配
回溯引用指的是模式的后半部分引用在前半部分中定義的子表達式,它允許正則表達式模式引用前面的匹配結(jié)果,可將其想像成變量.
回溯引用只能用來引用模式里的子表達式(用(和)括起來的正則表達式片段),其匹配通常從1開始計數(shù)(\1、\2,等等),在許多實現(xiàn)里,第0個(\0)可以用來代表整個正則表達式,同一個子表達式可以被引用任意多次。
我們來看一個例子,我們來html中的1級到6級標(biāo)題標(biāo)簽.
var reg = /<h[1-6]>.*?<\/h[1-6]>/
var str1 = '<h1> welcome to my homeoage</h1>'
var str2 = '<h2> welcome to my homeoage</2>'
var str3 = '<h1> welcome to my homeoage</h2>'
console.log(reg.test(str1)) // -> true
console.log(reg.test(str2)) // -> true
console.log(reg.test(str3)) // -> true
我們會發(fā)現(xiàn)最后一個字符串并不不是我們預(yù)期的結(jié)果,但是它匹配成功了. 要解決這個問題, 就要用到我們上面所提到的回溯?引用.
var reg = /<(h[1-6])>.*?<\/\1>/
var str1 = '<h1> welcome to my homeoage</h1>'
var str2 = '<h2> welcome to my homeoage</h2>'
var str3 = '<h1> welcome to my homeoage</h2>'
console.log(reg.test(str1)) // -> true
console.log(reg.test(str2)) // -> true
console.log(reg.test(str3)) // -> false
我們可以看到,我們的模式不會匹配到第三個字符串了.
前后查找
有的時候,我們需要用正則表達式標(biāo)記要匹配的文本的位置(而不僅僅是文本本身). 這樣,便引出了前后查找(lookaround,對某一位置的前,后內(nèi)容進行查找)的概念.
| 元字符 | 說明 |
|---|---|
| ?= | 向前查找 |
| ?<= | 向后查找 |
- 向前查找
向前查找其實就是一個以?=開頭的子表達式,而需要匹配的文本跟在=的后面.
例子:
var str1 = 'http://baidu.com' ;
var str2 = 'https://baidu.com' ;
// 我們想要查找文本中`:`前面的協(xié)議 .
var reg = /\w+(?=:)/;
console.log(reg.exec(str1)) // -> http
console.log(reg.exec(str2)) // -> https
- 向后查找
向后查找的操作符號是?<=,其功能與向前查找很類似.不過遺憾的是js的正則中沒有向后查找.所以我只能從書上摘抄一個例子了:
文本:
ABC01 : $23.45
HGG42 : $5.31
正則:
(?<=\$)[0-9.]+
結(jié)果:
23.45
5.31
提示: 正則的前后查找是一種匹配但不消費的模式.
嵌入條件
正則表達式語言還有一種威力強大但不常用的功能----在表達式的內(nèi)部嵌入條件處理功能.
-
正則表達式里的條件
正則表達式里的嵌入條件要用
?來定義.并且嵌入條件不外乎有以下兩種情況:- 根據(jù)一個回溯引用來進行條件處理.
- 根據(jù)一個前后查找來進行條件處理.
其語法結(jié)構(gòu)是這樣的
?(條件)true-regex|false-regex.這個語法接受一個條件和兩個將分別在這個條件得到滿足和不滿足時執(zhí)行的子表達式.看上去與三目運算符
?:很相似. -
回溯引用條件
我們舉個??(例子):
電話號碼:
123-456-7890
(123)-456-7890
我們要想用一個正則來匹配這個兩個電話號. 這種情況下,使用嵌入回溯引用條件,便可以很便捷的寫出模式.
正則:
(\()?\d{3}(?(1)\)|-)\d{3}-\d{4}
結(jié)果:
123-456-7890
(123)-456-7890
- 前后查找條件
前后查找條件只在一個向前查找或者向后查找操作取得成功的情況下才允許一個表達式被使.
來看一個例子:
文本:
11111
22222
33333-
44444.4444
正則:
\d{5}(?(?=-)-\d{4})
結(jié)果:
11111
22222
44444.4444
結(jié)論:在正則表達式模式里可以嵌入條件,只有當(dāng)條件得到(或者沒得到)滿足時,相應(yīng)的表達式才會被執(zhí)行.這種條件可以是一個回溯引用(含義是檢查該),也可以是一個前后查找操作.
實戰(zhàn)演練
-
郵箱正則
郵箱的正則表達式是我們常用的一種, 我們先說一下郵箱的格式:
在互聯(lián)網(wǎng)中,電郵地址的格式是:用戶名@主機名(域名)。@是英文“at”的意思,所以電子郵件地址是表示在某部主機上的一個用戶賬號(例:guest - at - email.xxx.xxx.net),電郵地址不是身份。---維基百科
分析一下便知道郵箱以
@為分割符號,分為用戶名和主機名兩部分.所以我們可以先寫用戶名的匹配.用戶名的第一個字符應(yīng)為字母 (a-z) 或數(shù)字,后面的字符可以有
.,-,\,_這些符號,但這些符號之后必須跟著英文字母或者數(shù)字.我們來寫一下用戶名的正則:var reg = /^[a-z0-9]+([.-\\_]*[a-z0-9]+)*$/簡單分析一下這個正則:
-
[a-z0-9]+表示至少有一個字母或者數(shù)字,符號開頭第一個字符是字母或者數(shù)字的要求. -
([.-\\_]*[a-z0-9]+)*表示子表達式([.-\\_]*[a-z0-9]+)可以有零個或者多個. - 分析一下子表達式
([.-\\_]*[a-z0-9]+),將其分成[.-\\_]*和[a-z0-9]+兩部分. -
[.-\\_]*表示.,-,\,_可以有零個或者多個. -
[a-z0-9]+表示字母或者數(shù)字至少有一個. - 所以
([.-\\_]*[a-z0-9]+)*組合起來便符合符號之后必須跟著英文字母或者數(shù)字的要求.
我們可以驗證一下:
-
var reg = /^[a-z0-9]+([.-\\_]*[a-z0-9]+)*$/
var str1 = 'abc'
var str2 = 'ab.c'
var str3 = 'abc.'
var str4 = '.abc'
var str5 = 'a.b.c'
console.log(reg.test(str1)) // -> true
console.log(reg.test(str2)) // -> true
console.log(reg.test(str3)) // -> false
console.log(reg.test(str4)) // -> false
console.log(reg.test(str5)) // -> true
剛好滿足要求.是不是很nice.接下來我們就該寫域名的正則了.
我們來看一下域名的要求:
- 可以包含英文字母(a-z,不區(qū)分大小寫)、數(shù)字(0-9),以及半角的連接符“-”(即中橫線),不能使用空格及特殊字符(如!、$、&、?等).
-
-不能單獨注冊或連續(xù)使用,不能放在開頭或結(jié)尾。 - 每級域名之間用
.分割.
其正則表達式如下:
/^([a-z0-9]([-]?[a-z0-9])*.)+[a-z0-9]{2,}$/
我們來分析一下:
將正則劃分成
([a-z0-9]([-]?[a-z0-9])*.)+二級(或二級以上級別)域名 和[a-z0-9]{2,}頂級域名兩部分.([a-z0-9]([-]?[a-z0-9])*.)+中的的([a-z0-9]([-]?[a-z0-9])*.)類似于xxx.這樣的格式,而+代表至少有一個子級別的域名,進一步分析這一部分.其中的
[a-z0-9]表示開頭第一個字符只能是數(shù)字或者字母.([-]?[a-z0-9])*符合了-不能單獨注冊或連續(xù)使用,不能放在開頭或結(jié)尾的要求.最后的
.則滿足了域名之間用.分割的要求.
我們可以來驗證一下:
var reg = /^([a-z0-9]([-]?[a-z0-9])*.)+[a-z0-9]{2,}$/
var str1 = 'baidu.com'
var str2 = '.com'
var str3 = 'baidu-.com'
var str4 = 'bai--du.com'
var str5 = 'b-a-i-d-u.com'
var str6 = "yun.baidu.com"
console.log(reg.test(str1)) // -> true
console.log(reg.test(str2))// -> false
console.log(reg.test(str3))// -> false
console.log(reg.test(str4))// -> false
console.log(reg.test(str5))// -> true
console.log(reg.test(str6))// -> true
最終把它們和在一起,我們便可以得到郵箱的正則表達式:
/^[a-z0-9]+([.\-\\_]*[a-z0-9]+)*@([a-z0-9]([-]?[a-z0-9])*\.)+[a-z0-9]{2,}$/
用在線工具將改正則表達式其圖形化.

結(jié)束語
<<正則表達式必知必會>>的筆記到這里就告一段落了. 但其中內(nèi)容卻也只是正則表達式的冰山一角.在編程這一道路上我們還有很長的路要走,但愿你我能一直堅持下去,不求攀登到最高的頂峰,只求看那更多的風(fēng)景.
