JavaScript種正則表達式有兩種定義方式,定義一個匹配相似 <%XXX%> 的字符串html
1. 構造函數正則表達式
var reg=new RegExp('<%[^%>]+%>','g');
2. 字面量ruby
var reg=/<%[^%>]%>/g;
正則表達式讓人望而卻步以一個重要緣由就是其轉義字符太多了,組合很是之多,可是正則表達式的元字符(在正則表達式中具備特殊意義的專用字符,能夠用來規定其前導字符)並很少函數
元字符:( [ { \ ^ $ | ) ? * + .spa
並非每一個元字符都有其特定意義,在不一樣的組合中元字符有不一樣的意義,分類看一下regexp
字符 | 含義 |
\t | 水平製表符 |
\r | 回車符 |
\n | 換行符 |
\f | 換頁符 |
\cX | 與X對應的控制字符(Ctrl+X) |
\v | 垂直製表符 |
\0 | 空字符 |
通常狀況下正則表達式一個字符(轉義字符算一個)對應字符串一個字符,表達式 ab\t 的含義是htm
可是咱們可使用元字符[]來構建一個簡單的類,所謂類是指,符合某些特徵的對象,是一個泛指,而不是特指某個字符了,咱們可使用表達式 [abc] 把字符a或b或c歸爲一類,表達式能夠匹配這類的字符對象
元字符[]組合能夠建立一個類,咱們還可使用元字符^建立反向類/負向類,反向類的意思是不屬於XXX類的內容,表達式 [^abc] 表示不是字符a或b或c的內容blog
按照上面的說明要是咱們但願匹配單個數字那麼表達式是這樣的ip
[0123456789]
若是是字母那麼。。。,好麻煩,正則表達式還提供了範圍類,咱們可使用 x-y來鏈接兩個字符表示從x到y的任意字符,這是個閉區間,也就是說包含x和ybenshen,這樣匹配小寫字母就很簡單了
[a-z]
要是想匹配全部字母呢?在[]組成的類內部是能夠連寫的,咱們還能夠這樣寫 [a-zA-Z]
剛纔使用正則咱們建立了幾個類,來表示數字,字母等,但這樣寫也非常麻煩,正則表達式爲咱們提供了幾個經常使用的預約義類來匹配常見的字符
字符 | 等價類 | 含義 |
. | [^\n\r] | 除了回車符和換行符以外的全部字符 |
\d | [0-9] | 數字字符 |
\D | [^0-9] | 非數字字符 |
\s | [ \t\n\x0B\f\r] | 空白符 |
\S | [^ \t\n\x0B\f\r] | 非空白符 |
\w | [a-zA-Z_0-9] | 單詞字符(字母、數字、下劃線) |
\W | [^a-zA-Z_0-9] | 非單詞字符 |
有了這些預約義類,寫一些正則就很方便了,好比咱們但願匹配一個 ab+數字+任意字符 的字符串,就能夠這樣寫了 ab\d.
正則表達式還提供了幾個經常使用的邊界匹配字符
字符 |
含義 |
^ |
以xx開頭 |
$ |
以xx結尾 |
\b |
單詞邊界,指[a-zA-Z_0-9]以外的字符 |
\B |
非單詞邊界 |
看個不負責任的郵箱正則匹配(切勿模仿,小括號後面會講到) \w+@\w+\.(com)$
以前咱們介紹的方法都是一一匹配的,若是咱們但願匹配一個連續出現20次數字的字符串難道咱們須要寫成這樣
\d\d\d\d...
爲此正則表達式引入了一些量詞
字符 | 含義 |
? | 出現零次或一次(最多出現一次) |
+ | 出現一次或屢次(至少出現一次) |
* | 出現零次或屢次(任意次) |
{n} | 出現n次 |
{n,m} | 出現n到m次 |
{n,} | 至少出現n次 |
看幾個使用量詞的例子
\w+\b Byron 匹配 單詞+邊界+Byron
(/\w+\b Byron/).test('Hi Byron'); //true (/\w+\b Byron/).test('Welcome Byron'); //true (/\w+\b Byron/).test('HiByron'); //false
\d+\.\d{1,3} 匹配三位小數的數字
看了上面介紹的量詞,也許愛思考的同窗會想到關於匹配原則的一些問題,好比{3,5}這個量詞,要是在句子種出現了十次,那麼他是每次匹配三個仍是五個,反正三、四、5都知足3~5的條件,量詞在默認下是儘量多的匹配的,也就是你們常說的貪婪模式
'123456789'.match(/\d{3,5}/g); //["12345", "6789"]
既然有貪婪模式,那麼確定會有非貪婪模式,讓正則表達式儘量少的匹配,也就是說一旦成功匹配不再也不繼續嘗試,作法很簡單,在量詞後加上 ? 便可
'123456789'.match(/\d{3,5}?/g); //["123", "456", "789"]
有時候咱們但願使用量詞的時候匹配多個字符,而不是像上面例子只是匹配一個,好比但願匹配Byron出現20次的字符串,咱們若是寫成 Byron{20} 的話匹配的是Byro+n出現20次,怎麼把Byron做爲一個總體呢?使用()就能夠達到次目的,咱們稱爲分組
(Byron){20}
若是但願匹配Byron或Casper出現20次該怎麼辦呢?可使用字符 | 達到或的功效
(Byron|Casper){20}
咱們看到圖中有個#1的東東,那是什麼?使用分組的正則表達式會把匹配項也放到分組中,默認就是按數字編號分發的,各異根據編號得到捕獲的分組內容,這個在一些但願具體操做第幾個匹配項的函數中頗有用
(Byron).(ok)
若是有分組嵌套的狀況,外面的組的編號靠前
((^|%>)[^\t]*)
有時候咱們不但願捕獲某些分組,只須要在分組內加上 ?: 就能夠了,着並不意味着該分組內容不屬於正則表達式,只是不會給這個分組加編號了而已
(?:Byron).(ok)
其實在C#等語言中分組還能夠起名字,不過JavaScript不支持
表達式 | 含義 |
exp1(?=exp2) | 匹配後面是exp2的exp1 |
exp1(?!exp2) | 匹配後面不是exp2的exp1 |
說的有些抽象,看個例子 good(?=Byron)
(/good(?=Byron)/).exec('goodByron123'); //['good'] (/good(?=Byron)/).exec('goodCasper123'); //null (/bad(?=Byron)/).exec('goodCasper123');//null
經過上面例子能夠看出 exp1(?=exp2) 表達式會匹配exp1表達式,但只有其後面內容是exp2的時候纔會匹配,也就是兩個條件,exp1(?!exp2) 比較相似
good(?!Byron)
(/good(?!Byron)/).exec('goodByron123'); //null (/good(?!Byron)/).exec('goodCasper123'); //['good'] (/bad(?!Byron)/).exec('goodCasper123');//null