没有人会觉得正则表达式难写
1. RegExp對象
JavaScript有兩種方式實例化RegExp對象
- 字面量
- 構造函數
字面量
const reg = /all/; console.log(reg); // /all/ 'This is all I have.'.replace(reg, 'ALL'); // This is ALL I have. 復制代碼構造函數
const reg = new RegExp('all'); console.log(reg); // /all/ 'This is all I have.'.replace(reg, 'ALL'); // This is ALL I have. 復制代碼2. 元字符
- 原義文本字符
- 元字符
原義文本字符
代表它本來含義的字符。比如正則表達式為 /abc/、/123/;它們分別匹配的是 abc、123 ,
元字符
在正則表達式中,有特殊含義的非數字字符。如:\b \d \w . + () 等。部分元字符的含義并不唯一,在不同的書寫方式,含義可能不同。
元字符表:tool.oschina.net/uploads/api…
3. 工具推薦
不是所有正則表達式都像前面寫的那么簡單,因為正則表達式語法有些復雜,我們在寫的時候多多少少也會有些錯誤,或者閱讀別人寫的正則表達式的時候也難理解。
如果把下面的正則表達式轉換成下圖,會有助于我們理解正則表達式的含義。
^http(|s):\/\/[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+\/$
給大家推薦一個工具 regexper.com
4. 量詞
| + | 出現一次或多次(至少出現一次) |
| ? | 出現零次或一次(最多出現一次) |
| * | 出現零次或多次(任意次) |
| {n} | 出現n次 |
| {n, m} | 出現n到m次 |
| {n,} | 至少出現n次 |
使用工具 regexper.com/ 圖解
\d{2,6}
5. 貪婪模式和非貪婪模式
從上面 4. 量詞 的例子中,'1234567890'.replace(/\d+/, 'a'); 輸出的是 a 而不是 a234567890;'1234567890'.replace(/\d{2,4}/, 'a'); 輸出的是 a567890 而不是 a34567890。
貪婪模式:正則表達式盡可能多的匹配,一直到匹配失敗
非貪婪模式:正則表達式盡可能少的匹配,一旦匹配成功就不再匹配
因為默認情況下,正則表達式都是使用貪婪模式做匹配的。如果想要讓正則表達式使用非貪婪模式匹配,在量詞后面加個 ? 即可。
'1234567890'.replace(/\d{2,4}/, 'a'); // a567890 '1234567890'.replace(/\d{2,4}?/, 'a'); // a34567890'1234567890'.replace(/\d+/, 'a'); // a '1234567890'.replace(/\d+?/, 'a'); // a234567890 復制代碼6. 類
- 正則表達式中,可以使用 [] 來構建一個類,正則表達式中的類是指符合某些特性的對象
字符類
正則表達式 [abcd] 是把 a、b、c、d 歸為一類,該表達式可以匹配這類字符
'12345a6b7c8D9e'.replace(/[abcd]/g, '|'); // 12345|6|7|8D9e 復制代碼范圍類
正則表達式提供了 [a-z] 來表示從 a 到 z 的任意字符(包含 a 和 z)
'1a2b3c4q5z'.replace(/[a-z]/g, '|'); // 1|2|3|4|5| '1a2b3c4T5Z'.replace(/[a-z]/g, '|'); // 1|2|3|4T5Z '1a2b3c4T5Z'.replace(/[a-zA-Z]/g, '|'); // 1|2|3|4|5| '1a2b3c4q5z'.replace(/[0-9]/g, '|'); // |a|b|c|q|z 復制代碼[a-zA-Z0-9]
預定義類
| \d | [0-9] | 數字字符 |
| \D | [^0-9] | 非數字字符 |
| \w | [a-zA-Z0-9_] | 字母、數字、下劃線(單詞字符) |
| \W | [^a-zA-Z0-9_] | 非字母、數字、下劃線(非單詞字符) |
| \s | [\t\n\x0B\f\r] | 空白字符 |
| \S | [^\t\n\x0B\f\r] | 非空白字符 |
| . | [^\n\r] | 除了換行、回車之外的任意字符 |
7. 邊界
| ^ | 以xxx開頭 |
| $ | 以xxx結尾 |
| \b | 單詞邊界 |
| \B | 非單詞邊界 |
9. 分組
作用
- 與 | 使用
- 與量詞使用
- 反向引用
與 | 使用
/http(|s):\/\//
/http(|s):\/\//.test('https://'); // true /http(|s):\/\//.test('http://'); // true /a(b|c)d/.test('ad'); // false /a(b|c)d/.test('abd'); // true /a(b|c)d/.test('acd'); // true 復制代碼與量詞使用
如何匹配 test 出現兩次 testtest ?
/test{2}/.test('testtest'); // false /test{2}/.test('testt'); // true /(test){2}/.test('testtest'); // true 復制代碼反向引用
含有分組的正則表達式匹配成功時,將子表達式匹配到的內容,保存到內存中一個以數字編號的組里,可以簡單的認為是對一個局部變量進行了賦值,這時就可以通過反向引用方式,引用這個局部變量的值。
很多情況下,我們可能需要將某種格式的字符串轉換成另一種格式的字符串。例如:將 05/28/2018 轉換成 2018-05-28;將Markdown語法的超鏈接 [Test](https://www.test.com/) 轉換成HTML的超鏈接 <a href="https://www.test.com/">Test</a>
'05/28/2018'.replace(/(\d{2})\/(\d{2})\/(\d{4})/, '$3-$1-$2'); // => 2018-05-28 '[Test](https://www.test.com/)'.replace(/\[(.+)\]\((http(|s):\/\/.+)\)/, '<a href="$2">$1</a>'); // => <a href="https://www.test.com/">Test</a> 復制代碼忽略分組
有時候我們在寫正則表達式的時候會多次使用分組,但有一些分組是不需要反向引用的,比如正則表達式 /http(|s):\/\// 中的分組,我們不需要進行反向引用,這時候我們應該使用 (?:) 來忽略分組
不忽略分組:
/http(|s):\/\//
忽略分組:
/http(?:|s):\/\//
10. 前瞻后顧
- 正則表達式是從頭部(左)向尾部(右)開始匹配的,文本的尾部方向稱為“前”,文本的頭部方向稱為“后”
- 前瞻:正則表達式在匹配到規則的時候,向前檢查是否符合斷言
- 后顧:正則表達式在匹配到規則的時候,向后檢查是否符合斷言
| 正向前瞻 | exp(?=assert) | 向前檢查符合斷言的 |
| 負向前瞻 | exp(?!assert) | 向前檢查不符合斷言的 |
| 正向后瞻 | (?<=assert)exp | 向后檢查符合斷言的 |
| 負向后瞻 | (?<!assert)exp | 向后檢查不符合斷言的 |
11. 修飾符
- global: 是否全文搜索,默認 false
- ignoreCase: 是否大小寫敏感,默認 false
- multiline: 是否多行搜索,默認 false
- lastIndex: 是當前表達式匹配內容的最后一個字符的下一個位置
- source: 正則表達式的文本字符
12. RegExp對象中 test() 和 exec()
test()
用于測試參數字符串中是否存在匹配正則表達式模式的字符串;如果存在則返回true,否則返回false
const reg = /\w/; reg.test('|'); // false reg.test('a'); // true reg.test('a'); // true 復制代碼當使用 g 全文搜索時,test 函數會出現如下問題:
上述問題其實是正則表達式對象的 lastIndex 屬性在作怪
如果正則表達式使用了全文搜索 g ,又想避免上述問題,應在執行 test 函數前先將 lastIndex 置 0
const reg = /\w/g; reg.test('ab'); // true reg.lastIndex = 0; reg.test('ab'); // true reg.lastIndex = 0; reg.test('ab'); // true 復制代碼exec()
使用正則表達式模式對字符串執行搜索,并將匹配到的結果以數組形式返回,如果沒有匹配,返回null
結果數組屬性
- index:匹配字符的第一個字符的位置
- input:被匹配的字符串
返回的數組
- 第一個元素是與正則表達式匹配的內容
- 第二個元素是與第一個子表達式相匹配的內容
- 第三個元素是與第二個子表達式相匹配的內容(以此類推)
現有如下字符串數組,我們使用 exec 從每個元素中提取圖片的路徑
const arr = ['[測試1](https://www.test1.com/img/img-1.png)','[測試1](http://www.test1.com/img/img-1.jpg)','[測試2](https://static.test2.com/image/haha/img-1.png)' ] 復制代碼正則表達式:
const reg = /\[.+\]\(http(|s):\/\/[a-zA-Z0-g_-]+(\.[a-zA-Z0-9_-]+)+\/((.+\/)+.+\.(png|jpg))\)/; 復制代碼 const res = reg.exec(arr[2]); 復制代碼上述正則表達式使用了較多的分組,我們在閱讀圖形的時候可能造成干擾,忽略不必要的分組。
const reg2 = /\[.+\]\(http(?:|s):\/\/[a-zA-Z0-g_-]+(?:\.[a-zA-Z0-9_-]+)+\/((?:.+\/)+.+\.(?:png|jpg))\)/; 復制代碼 reg2.exec(arr[2]); 復制代碼總結
以上是生活随笔為你收集整理的没有人会觉得正则表达式难写的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 腾讯云DevOps技术揭秘:新时代运维重
- 下一篇: VS2017调试闪退之Chrome