咱們在開發的過程當中總會碰到一些需求須要作字符串匹配,當遇到一些稍微複雜一點的匹配規則時,若是咱們對正則還不那麼清晰,咱們老是會去網上搜索一些現成的正則匹配,ctrl+c,ctrl+v。時間長了咱們對這種修修補補的方式不厭其煩。那麼今天就對正則表達式作足功夫,磨刀不誤砍柴工,首先推薦一個學習正則的一個可視化的工具網址: regexper.com,輸入正則規則便可生成匹配規則的流程圖。瞭解並吃透正則會爲咱們之後開發節省不少時間和精力,一勞永逸。先從最基本的概念開始吧,let go!git
概念:有特殊含義的特殊字符,eg: * + ? $ ^ . | \ ( ) { } [ ]等正則表達式
在大部分語言語境中表明同一種含義,以下表:數組
字符 | 含義 |
---|---|
\t | 水平製表符 |
\v | 垂直製表符 |
\n | 換行符 |
\r | 回車符 |
\0 | 空字符 |
\f | 換頁符 |
\cX | Ctrl+X |
字符 | 等價 | 含義 |
---|---|---|
. | [^\r\n] | 除了回車符和換行符以外的全部字符 |
\d | [0-9] | 數字字符 |
\D | [^0-9] | 非數字字符 |
\s | [\t\n\x0B\f\r] | 空白符 |
\0 | [^\t\n\x0B\f\r] | 非空白符 |
\w | [a-zA-Z_0-9] | 單詞字符(字母數字下劃線) |
\W | [^a-zA-Z_0-9] | 非單詞字符 |
字符 | 含義 |
---|---|
^ | 以xxx開始 |
$ | 以xxx結束 |
\b | 單詞邊界 |
\B | 非單詞邊界 |
字符 | 含義 |
---|---|
? | 出現一次或0次(最多出現一次) |
+ | 出現一次或屢次(最少出現一次) |
* | 出現0次或屢次(任意次) |
{n} | 出現n次 |
{n, m} | 出現n到m次 |
{n, } | 至少出現n次 |
'12345678'.replace(/\d{3,6}/, 'X') // "X78"
複製代碼
'12345678'.replace(/\d{3,6}?/, 'X') // "X45678"
複製代碼
對一組正則規則加(),能夠對正則進行分組,bash
好比:對taoyouyou這組單詞匹配三次 taoyouyou{3} svg
對字符串進行分組後,工具
捕獲組的編號是按照「(」出現的順序,從左到右,從1開始進行編號的 。學習
在replace方法中能夠經過$number(number表示捕獲組的編號)進行引用測試
在js表達式中分組引用經過RegExp對象暴露出來,ui
即經過RegExp.$number引用spa
例如實現2019-02-22 => 02/22/2019的轉化。
'2019-02-22'.replace(/(\d{4})-(\d{2})-(\d{2})/,'$2/$3/$1') // "02/22/2019"
複製代碼
正則表達式中所定義的捕獲的反向引用指的是
將捕獲做爲正則表達式中可以成功匹配術語時的候選字符串
這種術語表示法是在反斜杆後面加一個要引用的捕獲數量。
捕獲組捕獲到的內容,不只能夠在正則表達式外部經過程序進行引用,也能夠在正則表達式內部進行引用,這種引用方式就是反向引用。反向引用的做用一般是用來查找或限定重複、查找或限定指定標識配對出現等等。 例如:([a-z])\1{2}也就表達連續三個相同的小寫字母。
不須要捕獲某些分組只須要在分組內加 ?: 就能夠了。 (?:taoyouyou).(ok)
名稱 | 正則 | 含義 |
---|---|---|
正向前瞻 | exp(?=assert) | |
負向前瞻 | exp(?!assert) | |
正向後顧 | exp(?<=assert) | JavaScript不支持 |
負向後顧 | exp(?<!assert) | JavaScript不支持 |
reg=/\d/gmi
reg.global // true
reg.ignoreCase // true
reg.multiline // true
reg.lastIndex // 0
reg.source // "\d"
複製代碼
RegExp.prototype.test(str)
須要注意的是:
var reg2=/\w/g;
複製代碼
進行reg2.test('ab')時,第三次會變成false 緣由:
while(reg2.test('ab')){
console.log(reg2.lastIndex);
}
複製代碼
即進行test時,正則表達式的lastIndex會發生變化 輸出:1 2 表示第一個匹配上了、第二個匹配上了
RegExp.prototype.exec(str)
var reg3=/\d(\w)(\w)\d/; // 非全局搜索只能匹配到第一個結果
var reg4=/\d(\w)(\w)\d/g; // 全局搜索匹配全文
var ts = '$1az2bb3cy4dd5ee'
var ret1= reg3.exec(ts) // (3) ["1az2", "a", "z", index: 1, input: "$1az2bb3cy4dd5ee", groups: undefined]
console.log(reg3.lastIndex+'\t'+ret1.index+'\t'+ret1.toString())
// "0 1 1az2, a, z"
while(ret2 = reg4.exec(ts)){
console.log(reg4.lastIndex+'\t'+ret2.index+'\t'+ret2.toString())
}
// "5 1 1az2, a, z"
// "11 7 1az2, a, z"
複製代碼
String.prototype.search(reg)
String.prototype.match(reg)
var reg3=/\d(\w)(\w)\d/; // 非全局搜索只能匹配到第一個結果
var reg4=/\d(\w)(\w)\d/g; // 全局搜索匹配全文
var ts = '$1az2bb3cy4dd5ee'
var ret1= ts.match(reg3) // (3) ["1az2", "a", "z", index: 1, input: "$1az2bb3cy4dd5ee", groups: undefined]
console.log(reg3.lastIndex+'\t'+ret1.index) // 0, 1
var ret2 = ts.match(reg4) // (2) ["1az2", "3cy4"]
console.log(reg4.lastIndex+'\t'+ret2.index) // 0 undefined
複製代碼
String.prototype.split(reg)
String.prototype.replace
'a1b2c3d4e5'.replace(/\d/g, function(match, index, origin){
return parseInt(match) + 1;
}) // "a2b3c4d5e6"
'a1b2c3d4e5'.replace(/(\d)(\w)(\d)/g, function(match, group1, group2, group3, index, origin){
console.log(match)
return group1 + group3;
})
// 1b2
// 3d4
// "a12c34e5"
複製代碼