正則表達式,又稱正規表示法、正規表達式、規則表達式、常規表示法(英語:Regular Expression,在代碼中常簡寫爲regex、regexp或RE),計算機科學的一個概念。正則表達式使用單個字符串來描述、匹配一系列符合某個句法規則的字符串。在不少文本編輯器裏,正則表達式一般被用來檢索、替換那些符合某個模式的文本。javascript
說人話就是:對字符串執行模式匹配的強大工具。前端
Javascript中的正則表達式相較於其餘語言來講實現的並不完整,但仍然是十分強大的,可以幫助咱們完成絕大多數模式匹配任務。java
在javascript中,正則表達式的定義和數組以及對象的定義同樣有倆種方式。 一種是直接量,另外一種是構造函數。node
Javascript可使用相似Perl的語法定義一個正則表達式正則表達式
var r = /pattern/flags;
其中pattern是任何簡單或複雜的正則表達式,flags是用以表達正則表達式行爲的一個或者多個標識。
數組
flags編輯器
g 表示全局(global)模式,即模式將被應用於全部字符串函數
i 表示不區分大小寫工具
m 多行模式編碼
舉個栗子:
var reg1 = /ip/g; // 匹配字符串中全部'ip'的實例 var reg2 = /com/gi; // 匹配以'com'結尾的三個字符的組合,不區分大小寫
Javascript中正則表達式的構造函數爲RegExp,即Regular Expression的縮寫,它接收兩個參數,第一個爲要匹配的字符串模式,另外一個是可選的標識位。
var reg = new RegExp('nice', 'g'); // 匹配字符串中全部的'nice'
注意:第一個參數是一個字符串nice
,而不是正則表達式的直接量/nice/
。
全部元字符都須要進行雙重轉義
全部元字符都須要進行雙重轉義
全部元字符都須要進行雙重轉義
使用構造函數
定義正則表達式,因爲構造函數的第一個參數必須是一個字符串,在匹配元字符時,須要雙重轉義。
// 匹配{user} var reg1 = new RegExp('\{user\}', 'g'); // wrong // 因爲\在字符串中須要轉義爲\\,因此,若是要匹配{user},正則表達式須要寫爲 var reg1 = new RegExp('\\{user\\}', 'g');
在正則表達式的模式中,有一些字符是有特殊含義的,被稱爲元字符,若是要匹配元字符,則必須對其進行轉義,若是用構造函數,則要進行雙重轉義。
這些元字符分別是(一共14個):
{ ( [ \ ^ $ | ? * + . ] ) }
| 字符 | 匹配 |
| ------------- |:-------------:|
|字母數字字符|自身|
|\0 |查找 NUL 字符。|
|\n |查找換行符。|
|\f |查找換頁符。|
|\r |查找回車符。|
|\t |查找製表符。|
|\v |查找垂直製表符。|
|\xxx |查找以八進制數 xxx 規定的字符。|
|\xdd |查找以十六進制數 dd 規定的字符。|
|\uxxxx |查找以十六進制數 xxxx 規定的 Unicode 字符。|
無論一個直接量字符字符表明何種含義,單個字符始終只匹配單個字符
| 字符 |等價於| 匹配 |
| ------------- |:-------------:| :-------------:|
| . | 1|查找單個字符,除了換行和行結束符。 |
| \w| [a-zA-Z_0-9]|任意ASCII單字字符,等價於[a-zA-Z0-9_]|
| \W| 2 |查找非單詞字符。 |
|\d |[0-9]|查找數字。|
|\D |3|查找非數字字符。|
|\s |[ \t\n\x0B\f\r]|查找空白字符。|
|\S |4|查找非空白字符。|
|[]||來表示單個字符有或的關係,如/[bc]/,匹配b或者c|
|^||來表示不匹配後面跟着的字符,如/5,/不匹配b或c|
|-||來表示一個範圍,如/[a-z]/,匹配a-z的字母,能夠和負向類結合/^0-9/|
|組合類:||以上幾種類組合而成的字符類,如/a-z0-9\n/,匹配a-z的字母或者0-9的數字或者換行符|
注意:在javascript類不能嵌套,就是不支持聯合類和交叉類,/a-m[p-z]/和/a-m6/在JavaScript中是非法的
| 字符 | 含義|
| ------------- |:-------------:|
| ^ | 匹配字符串的開頭,在多行檢索中,匹配一行的開頭|
| $| 匹配字符串的結尾,在多行檢索中,匹配一行的結尾|
|\b |匹配單詞邊界。|
|\B |匹配非單詞邊界。|
| 經常使用量詞 | {m,n}等價形式|描述 |
| ------------- |:-------------:| :-------------:|
|?|{0,1}|最多出現1次,例如,do(es)? 匹配 do 或 does 中的 do|
|* |{0,}|可能出現,也可能不出現,出現次數無上限,例如,zo* 匹配 z 和 zoo。|
|+ |{1,}|最少出現1次,例如,zo+ 匹配 zo 和 zoo,但不匹配 z|
在正則表達式概念中,稱 +、*、?爲經常使用量詞,稱{n,m}形式的爲通用量詞。
**?的使用
**
情景:美式應用和英式語言的單詞寫法不一樣,好比traveler和traveller.
var str1 = 'traveler'; var str2 = 'traveller'; var pattern = /travell?er/; console.log(pattern.test(str1)); console.log(str2.search(str2)); 結果打印: true 0
匹配各種標籤(前端應用)
貪婪量詞:先匹配整個字符串,若是不匹配則去掉最後一個字符再匹配,直到沒有任何字符。它是從後向前匹配。全部簡單量詞都是貪婪的
。
惰性量詞:和貪婪量詞相反,即先匹配第一個字符,不匹配則匹配第一第二個字符,直到最後整個字符串。全部簡單量詞後面加?就是惰性的了
。
支配量詞:只匹配整個字符串一次,不匹配就結束,也稱最懶量詞,全部簡單量詞後面加+就是支配的了,可是javascript不支持,因此它連出場的機會也沒有了。
。
舉個栗子(complex-quantifiers.js):
var re1 = /.*bbb/g; // 定義貪婪量詞 var re2 = /.*?bbb/g; // 定義簡單惰性 // var re3 = /.*+bbb/g;//支配性,javascript不支持,nodejs報錯 var str='abbbaabbbaaabbb1234'; console.log(re1.test(str)); //true console.log(re1.exec(str)); //null console.log(str.match(re1)); //abbbaabbbaaabbbb console.log(re2.test(str)); //true console.log(re2.exec(str)); //aabbb console.log(str.match(re2)); //abbb,aabbb,aaabbb
到目前爲止,咱們只能一個字符到匹配,雖然量詞的出現,能幫助咱們處理一排密緊密相連的同類型字符。但這是不夠的,下面該輪到小括號出場了,中括號表示範圍內選擇,大括號表示重複次數。小括號容許咱們重複多個字符。
舉個栗子(group.js):
//分組+量詞 console.log(/(dog){2}/.test("dogdog"))//true //分組+範圍 console.log("baddad".match(/([bd]ad?)*/))//baddad,dad //分組+分組 console.log("mon and dad".match(/(mon( and dad)?)/))//mon and dad,mon and dad, and dad
|優先級| 符號|說明|
| ------------- |:-------------:| :-------------:|
|最高 |\|轉義符|
|高 |( )、(?: )、(?= )、[ ]|單元和字符類|
|中 |*、+、?、{n}、{n,}、{m,n}|量詞|
|低 |^、$、\任何元字符、任何字符|描點|
|最低|\||替換,選擇|
參考加減乘除,先算括號內的記憶方式
global 屬性 | ignoreCase 屬性 | multiline 屬性 | source 屬性
global: 返回布爾值,該值指示使用正則表達式的 global 標誌 (g) 的狀態。 默認值爲 false。 只讀。
ignoreCase: 返回布爾值,該值指示在正則表達式中使用的 ignoreCase 標誌 (i) 的狀態。 默認值爲 false。 只讀。
multiline: 返回布爾值,該值指示在正則表達式中使用的 multiline 標誌 (m) 的狀態。 默認值爲 false。 只讀。
source: 返回正則表達式模式的文本的一個副本。 只讀。
lastIndex: 若是使用了全局模式,這個變量保存的是字符串中嘗試下次匹配的偏移值。在exec和test中都會用到這個變量。 可寫
RegExp 對象有 3 個方法:test()、exec() 以及 compile()
test 方法檢查字符串中是否存在某種模式,若是存在,則返回 true,不然返回 false。test 方法不修改全局 RegExp 對象的屬性。
語法:
rgExp.test(str) // 參數 rgExp 必需。 包含正則表達式模式和適用標誌的 Regular Expression 對象的實例。 str 必需。 將對其執行搜索的字符串。
栗子:
var str = 'huangge is an handsome man'; var reg1 = new RegExp( 'handsome', 'g' ); var result = reg1.test(str); console.log('huangge is an handsome man: ' + result);
exec 方法使用正則表達式模式對字符串執行需找匹配,若是成功,則返回表示匹配信息的數組,不然返回null。默認狀況下,它返回第一次匹配的結果
語法:
rgExp.exec(str) // 參數 rgExp 必需。 包含正則表達式模式和適用標誌的 Regular Expression 對象的實例。 str 必需。 對其執行搜索的 String 對象或字符串文本。
返回值
若是成功匹配,exec 方法返回一個數組,而且更新正則表達式對象的屬性。返回的數組包括匹配的字符串做爲第一個元素,緊接着一個元素對應一個成功匹配被捕獲的字符串的捕獲括號(capturing parenthesis)。
若是匹配失敗,exec 方法將返回 null。
栗子(regexp-exec.js):
var reg= /\d{4}-\d{2}-\d{2}/g; var str = 'aaa2015-08-11aaaaaabbss2015-08-22bbb'; var result = reg.exec(str); console.log(result); 結果以下: [ '2015-08-11', index: 3, input: 'aaa2015-08-11aaaaaabbss2015-08-22bbb' ]
將正則表達式編譯爲內部格式,從而更快地執行。
語法:
rgExp.compile(pattern, [flags]) // 參數 rgExp 必需。 Regular Expression 對象的一個實例。 能夠是變量名或文本。 pattern 必需。 一個字符串表達式,包含要編譯的正則表達式模式 flags 可選。 能夠組合使用的可用標誌有: g(全局搜索出現的全部模式) i(忽略大小寫) m(多行搜索)
compile 方法將 pattern 轉換爲內部的格式,從而執行得更快。 例如,這容許在循環中更有效地使用正則表達式。 當重複使用相同的表達式時,編譯過的正則表達式使執行加速。 然而,若是正則表達式發生更改,則這種編譯毫無益處。
這個方法相似RegExp.exec(string),只是調換了RegExp和string的位置。 另外一個區別就是,不管是否指定全局,RegExp.exec(string)只是返回單詞匹配結果。 而string.match()會返回一個字符串數組,其中包含了各次匹配成功的文本
舉個栗子(string-match.js):
var reg= /\d{4}-\d{2}-\d{2}/g; var str = 'aaa2015-08-11aaaaaabbss2015-08-22bbb'; var result = str.match(reg); console.log(result); 打印的結果爲: [ '2015-08-11', '2015-08-22' ]
這個用來尋找某個正則表達式在字符串第一次匹配成功的位置,若是不成功,則返回-1
舉個栗子(string-search.js):
var str1 = 'sssssaa111'; var str2 = 'sssssaaaaa'; var pattern = /\d/; console.log ('st1 ' + str1.search(pattern)); console.log ('st2 ' + str2.search(pattern)); 打印的結果爲: st1 7 st2 -1
這個方法用來正則表達式替換。 將匹配到的文本替換爲replacement。默認狀況替換一次。若是設定了全局模式,則全部能匹配的文本都會替換。
舉個栗子(string-replace.js):
var reg = /\d{4}-\d{2}-\d{2}/; var str = '2015-08-11 2015-08-22'; console.log(str.replace(reg, 'Date:')); 打印的結果爲: ate: 2015-08-22
這個方法使用一個正則表達式切分字符串,正則表達式是否使用全局對結果沒有影響
舉個栗子(string-split.js):
var str = 'one two three four'; var pattern = /\s+/; console.log(str.split(pattern)) 打印的結果爲: [ 'one', 'two', 'three', 'four' ]
匹配中文字符的正則表達式: [\u4e00-\u9fa5]
匹配雙字節字符(包括漢字在內):10
評註:能夠用來計算字符串的長度(一個雙字節字符長度計2,ASCII字符計1)
匹配空白行的正則表達式:\n\s*\r
匹配HTML標記的正則表達式:<(\S?)7>.?</\1>|<.? />
匹配首尾空白字符的正則表達式:^\s|\s$
匹配Email地址的正則表達式:\w+([-+.]\w+)@\w+([-.]\w+)\.\w+([-.]\w+)*
匹配網址URL的正則表達式:[a-zA-z]+://11*
匹配賬號是否合法(字母開頭,容許5-16字節,容許字母數字下劃線):^a-zA-Z{4,15}$
匹配國內電話號碼:\d{3}-\d{8}|\d{4}-\d{7}
匹配騰訊QQ號:1-9{4,}
匹配中國郵政編碼:[1-9]\d{5}(?!\d)
匹配身份證:\d{15}|\d{18}
匹配ip地址:\d+\.\d+\.\d+\.\d+
^[1-9]\d*$ //匹配正整數 ^-[1-9]\d*$ //匹配負整數 ^-?[1-9]\d*$ //匹配整數 ^[1-9]\d*|0$ //匹配非負整數(正整數 + 0) ^-[1-9]\d*|0$ //匹配非正整數(負整數 + 0) ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ //匹配正浮點數 ^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ //匹配負浮點數 ^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$ //匹配浮點數 ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$ //匹配非負浮點數(正浮點數 + 0) ^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$ //匹配非正浮點數(負浮點數 + 0)
^[A-Za-z]+$ //匹配由26個英文字母組成的字符串 ^[A-Z]+$ //匹配由26個英文字母的大寫組成的字符串 ^[a-z]+$ //匹配由26個英文字母的小寫組成的字符串 ^[A-Za-z0-9]+$ //匹配由數字和26個英文字母組成的字符串 ^\w+$ //匹配由數字、26個英文字母或者下劃線組成的字符串