在平時的工做中經常會碰到正則,可是我發現,每次都忘記該怎麼去寫,因此在這裏稍微複習總結一下
/* 題目一 */ var str1 = '123456765464153513566' // 分割數字每三個以一個逗號劃分(從後往前) // 如1234 -> 1,234 /* 題目二 */ var str2 = "get-element-by-id" // 將-的命名方式改成小駝峯 // 指望結果getElementById /* 題目三 */ var str3 = 'getElementById' console.log(str3.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase()) // 寫出運行結果
看完這三個題目,你是否有想法,下面公佈答案git
// 題目一 console.log(str1.replace(/(\d)(?=(\d{3})+$)/g,'$1,')) // 123,456,765,464,153,513,566 // 題目二 console.log(str2.replace(/-\w/g, ($0) => { return $0.slice(1).toUpperCase() })) // getElementById // 題目三 // get-element-by-id
若是你的答案所有正確,那麼請忽略下面的內容正則表達式
apple
這個單詞裏找到a
這個字符,就直接用/a/
這個正則就能夠了*
,須要使用\
來轉義去掉其原本的含義,正則就能夠寫成/\*/
特殊字符 | 正則表達式 | 記憶方式 |
---|---|---|
換行符 | n | new line |
換頁符 | f | form feed |
回車符 | r | return |
空白符 | s | space |
製表符 | t | tab |
垂直製表符 | v | vertical tab |
回退符 | [b] | backspace,之因此使用[]符號是避免和b重複 |
[
和]
,如/[123]/
這個正則就能同時匹配1,2,3三個字符。用/[0-9]/
就能匹配全部的數字, /[a-z]/
則能夠匹配全部的英文小寫字母匹配區間 | 正則表達式 | 記憶方式 |
---|---|---|
除了換行符以外的任何字符 | . | 句號,除了句子結束符 |
單個數字, [0-9] | d | digit |
除了[0-9] | D | not digit |
包括下劃線在內的單個字符,[A-Za-z0-9_] | w | word |
非單字字符 | W | not word |
匹配空白字符,包括空格、製表符、換頁符和換行符 | s | space |
匹配非空白字符 | S | not space |
?
表明了匹配一個字符或0個字符, 例匹配 color
和 colour
這兩個單詞, 就能夠寫爲 /colou?r/
*
用來表示匹配0個字符或無數個字符, 例匹配 color
和colouuuuuur
就能夠寫爲 /colou*r/
color
和colour
這兩個單詞, 若使用 /colou+r/
來匹配,就只能匹配到colour
匹配特定的次數, 可使用元字符 {
和 }
用來給重複匹配設置精確的區間範圍。如 a
我想匹配3次,那麼我就使用 /a{3}/
這個正則,或者說 a
我想匹配至少兩次就是用 /a{2,}/
這個正則。app
總結
| 匹配規則 | 元字符 |
| :-----:| :----: |
| 0次或1次 | ? |
| 0次或無數次 | * |
| 1次或無數次 | + |
| 特定次數 | {x}, {min, max} |
\b
, 例 The cat scattered his food all over the room.
匹配出全部的單詞cat
, 就能夠寫成 /\bcat\b/g
^
用來匹配字符串的開頭。而元字符$
用來匹配字符串的末尾。邊界總結:post
邊界和標誌 | 正則表達式 | 記憶方式 |
---|---|---|
單詞邊界 | b | boundary |
非單詞邊界 | B | not boundary |
字符串開頭 | ^ | - |
字符串結尾 | $ | - |
多行模式 | m標誌 | multiple of lines |
忽略大小寫 | i標誌 | ignore case, case-insensitive |
全局模式 | g標誌 | global |
全部以 (
和 )
元字符所包含的正則表達式被分爲一組,每個分組都是一個子表達式
,它也是構成高級正則表達式的基礎。spa
回溯引用(backreference)指的是後面部分引用前面已經匹配到的子字符串。你能夠把它想象成是變量,回溯引用的語法像\1
, \2
,....,其中 \1
表示引用的第一個子表達式,\2
表示引用的第二個子表達式,以此類推。而 \0
則表示整個表達式。code
// 例如 // 匹配下面字符串中兩個連續的單詞 // Hello what what is the first thing, and I am am scq000. var str4 = 'Hello what what is the first thing, and I am am scq000.' console.log(str4.match(/\b(\w+)\s\1/g))
用 $1
, $2
...來引用要被替換的字符串orm
var str = 'abc abc 123'; str.replace(/(ab)c/g,'$1g'); // 獲得結果 'abg abg 123'
若是咱們不想子表達式被引用,可使用非捕獲正則(?:regex)這樣就能夠避免浪費內存。ip
var str = 'scq000'. str.replace(/(scq00)(?:0)/, '$1,$2') // 返回scq00,$2 // 因爲使用了非捕獲正則,因此第二個引用沒有值,這裏直接替換爲$2 var str4 = 'scq000 scq001' console.log(str4.replace(/(scq00)(?:0)/, '$1,$2')) // 返回 scq00,$2 scq001
前向查找(lookahead)是用來限制後綴的。凡是以 (?=regex)
包含的子表達式在匹配過程當中都會用來限制前面的表達式的匹配。例如happy
happily
這兩個單詞,我想得到以 happ
開頭的副詞,那麼就可使用/happ(?=ily)/
來匹配, 就能夠匹配到單詞happily
的happ
前綴。若是我想過濾全部以 happ
開頭的副詞,那麼也能夠採用負前向查找的正則/happ(?!ily)/
,就會匹配到happy
單詞的happ
前綴。內存
後向查找(lookbehind)是經過指定一個子表達式,而後從符合這個子表達式的位置出發開始查找符合規則的字串。舉個簡單的例子: apple
和 people
都包含 ple
這個後綴,那麼若是我只想找到 apple
的 ple
,該怎麼作呢?咱們能夠經過限制app這個前綴,就能惟一肯定 ple
這個單詞了。element
var str4 = 'apple people'; console.log(str4.replace(/(?<=ap)ple/,'-')) // 獲得結果 'ap- people' // 說明匹配到的是單詞apple的ple
(?<=regex)
的語法就是後向查找,regex
指代的子表達式會做爲限制項進行匹配,匹配到這個子表達式後,就會繼續向後查找。另一種限制匹配是利用(?<!regex)
語法,這裏稱爲負後向查找。與正前向查找不一樣的是,被指定的子表達式不能被匹配到。因而,在上面的例子中,若是想要查找 apple
的ple
也能夠寫成/(?<!peo)ple
總結
| 回溯查找 | 正則 |
| :-----:| :----: |
| 引用 | 0,1,2 和 $0, $1, $2 |
| 非捕獲組 | (?:) |
| 前向查找 | (?=) |
| 前向負查找 | (?!) |
| 後向查找 | (?<=) |
| 後向負查找 | (?<!) |
[
和 ]
內部使用的 ^
表示非的關係(?!regex)
或後向負查找子表達式(?<!regex)
(a|b)
這樣的子表達式。到這裏正則差很少已經複習了一遍,咱們如今再去看前面的三道題
/* 題目一 */ var str1 = '123456765464153513566' // 分割數字每三個以一個逗號劃分(從後往前) // 如1234 -> 1,234 console.log(str1.replace(/(\d)(?=(\d{3})+$)/g,'$1,')) // 123,456,765,464,153,513,566
解析:\d
表示單個數字,(?=(\d{3})+$)
是一個前向查找,\d{3})+$
表示匹配3位數字一次或者屢次而且以三位數字結尾。連在一塊兒看就是,匹配一個數字,數字後面的數字位數是3的倍數,因此匹配到的數字是3, 6, 5, 4, 3, 3
,而後替換爲$1,
,故3
替換爲3,
、 6
替換爲6,
....
/* 題目二 */ var str2 = "get-element-by-id" // 將-的命名方式改成小駝峯 // 指望結果getElementById console.log(str2.replace(/-\w/g, ($0) => { return $0.slice(1).toUpperCase() }))
解析:首先/-\w/g
的意思是匹配全部前面是-
的單個字符
,匹配的結果是-e, -b, -i
, 而後取其第二位(也就是將-
截取掉),再轉換爲大寫
/* 題目三 */ var str3 = 'getElementById' console.log(str3.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase()) // 寫出運行結果 // 答案:get-element-by-id
解析: ([a-z])([A-Z])
的意思就是匹配兩個字母,而且第一個是小寫,第二個是大寫,因此匹配到的結果是tE, tB, yI
,因爲()
表明分組,故$1
表明的是匹配到的小寫字母,$2
表明的是匹配到的大寫字母
參考: 正則表達式不要背