JavaScript有兩種方式實例化RegExp對象javascript
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.
表明它原本含義的字符。好比正則表達式爲/abc/
、/123/
;它們分別匹配的是abc
、123
,
在正則表達式中,有特殊含義的非數字字符。如:\b
\d
\w
.
+
()
等。部分元字符的含義並不惟一,在不一樣的書寫方式,含義可能不一樣。
元字符表:http://tool.oschina.net/uploads/apidocs/jquery/regexp.htmlhtml
不是全部正則表達式都像前面寫的那麼簡單,由於正則表達式語法有些複雜,咱們在寫的時候多多少少也會有些錯誤,或者閱讀別人寫的正則表達式的時候也難理解。java
若是把下面的正則表達式轉換成下圖,會有助於咱們理解正則表達式的含義。jquery
^http(|s):\/\/[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+\/$
正則表達式
給你們推薦一個工具 https://regexper.comapi
字符 | 含義 |
---|---|
+ | 出現一次或屢次(至少出現一次) |
? | 出現零次或一次(最多出現一次) |
* | 出現零次或屢次(任意次) |
{n} | 出現n次 |
{n, m} | 出現n到m次 |
{n,} | 至少出現n次 |
// \d表示匹配數字 // 匹配一個數字 '1234567890'.replace(/\d/, 'a'); // a234567890 // 匹配一個或多個數字(至少匹配一個) '1234567890'.replace(/\d+/, 'a'); // a '1234567890'.replace(/\d?/, 'a'); // a234567890 '1234567890'.replace(/\d*/, 'a'); // a '1234567890'.replace(/\d{3}/, 'a'); // a4567890 '1234567890'.replace(/\d{2,4}/, 'a'); // a567890 '1234567890'.replace(/\d{3,}/, 'a'); // a '12'.replace(/\d{3,}/, 'a'); // 12
使用工具 https://regexper.com/ 圖解數組
\d{2,6}
函數
從上面 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
[]
來構建一個類,正則表達式中的類是指符合某些特性的對象正則表達式[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] | 除了換行、回車以外的任意字符 |
字符 | 含義 |
---|---|
^ | 以xxx開頭 |
$ | 以xxx結尾 |
\b | 單詞邊界 |
\B | 非單詞邊界 |
'img/png/img-1.png'.replace(/img/g, 'image'); // image/png/image-1.png 'img/png/img-1.png'.replace(/^img/g, 'image'); // image/png/img-1.png 'img/png/img-1.png'.replace(/png/g, 'jpg'); // img/jpg/img-1.jpg 'img/png/img-1.png'.replace(/png$/g, 'jpg'); // img/png/img-1.jpg 'This is all I have.'.replace(/is/g, 'IS'); // ThIS IS all I have. 'This is all I have.'.replace(/\bis\b/g, 'IS'); // This IS all I have. 'This is all I have.'.replace(/\Bis\b/g, 'IS'); // ThIS is all I have.
/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
如何匹配 javascript
出現兩次 javascriptjavascript
?
/javascript{2}/.test('javascriptjavascript'); // false /javascript{2}/.test('javascript'); // true /(javascript){2}/.test('javascriptjavascript'); // 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):\/\//
名稱 | 正則 | 含義 |
---|---|---|
正向前瞻 | exp(?=assert) | 向前檢查符合斷言的 |
負向前瞻 | exp(?!assert) | 向前檢查不符合斷言的 |
正向後瞻 | (?<=assert)exp | 向後檢查符合斷言的 |
負向後瞻 | (?<!assert)exp | 向後檢查不符合斷言的 |
'ab1cde2fg'.replace(/[a-z](?=\d)/g, 'X'); // aX1cdX2fg 'ab1cde2fg'.replace(/[a-z](?!\d)/g, 'X'); // Xb1XXe2XX 'ab1cde2fg'.replace(/(?<=\d)[a-z]/g, 'X'); // ab1Xde2Xg 'ab1cde2fg'.replace(/(?<!\d)[a-z]/g, 'X'); // XX1cXX2fX
'aaaaa'.replace(/a/, 'A'); // Aaaaa 'aaaaa'.replace(/a/g, 'A'); // AAAAA 'aAQq'.replace(/[a-z]/g, 'X'); // XAQX 'aAQq'.replace(/[a-z]/gi, 'X'); // XXXX /[a-z]/.test('AA'); // false /[a-z]/i.test('AA'); // true `img/png/img-1.png img/png/img-1.png img/png/img-1.png`.replace(/^img/g, 'image'); // => image/png/img-1.png // img/png/img-1.png // img/png/img-1.png `img/png/img-1.png img/png/img-1.png img/png/img-1.png`.replace(/^img/gm, 'image'); // => image/png/img-1.png // image/png/img-1.png // image/png/img-1.png const reg = /\d/gim; console.log(reg.source); // \d
用於測試參數字符串中是否存在匹配正則表達式模式的字符串;若是存在則返回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
使用正則表達式模式對字符串執行搜索,並將匹配到的結果以數組形式返回,若是沒有匹配,返回null
結果數組屬性
返回的數組
現有以下字符串數組,咱們使用 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]);