[TOC]
* * * * *
### 1. 描述
正則表達式用來匹配字符串中的部分或全部,以做其他操作。
在Javascript中正則表達式是對象,有兩個常用方法 exec,test;
| 方法名 | 描述 |
| --- | --- |
| `exec` | 一個在字符串中執行查找匹配的 `RegExp` 方法,它返回一個數組(未匹配到則返回 `null`)。|
| `test` | 一個在字符串中測試是否匹配的 `RegExp` 方法,它返回 `true` 或 `false` 。`test`,表示如果檢測的字符串里有部分滿足正則規則,那就返回 `true`,如果想要檢驗整個字符串是否滿足某個規則,則對首尾的字符都要做檢測。|
`String` 的方法:
| 方法名 | 描述 |
| --- | --- |
|`match`|一個在字符串中執行查找匹配的 `String` 方法,它返回一個數組或者在未匹配到時返回 `null` 。|
|`search`|一個在字符串中測試匹配的 `String` 方法,它返回匹配到的位置索引,或者在失敗時返回 `-1` 。|
|`replace`|一個在字符串中執行查找匹配的 `String` 方法,并且使用替換字符串替換掉匹配到的子字符串。|
|`split`|一個使用正則表達式或者一個固定字符串分隔一個字符串,并將分隔后的子字符串存儲到數組中的 `String` 方法。|
>[warning]PS:當你想要知道在一個字符串中的一個匹配是否被找到,你可以使用 `test` 或 `search` 方法;
想得到更多的信息(但是比較慢)則可以使用 `exec` 或 `match` 方法。
如果你使用 `exec` 或 `match` 方法并且匹配成功了,那么這些方法將返回一個數組并且更新相關的正則表達式對象的屬性和預定義的正則表達式對象(詳見下)。
如果匹配失敗,那么 `exec` 方法返回 `null`(也就是 `false`)。
### 2. 創建
~~~
使用字面量形式的構造方法,簡潔,更好的性能,創建后就不再改變。
const reg1=/a|c+/;
還可以加修飾符
const reg2=/a|c+/g;
換成用構造函數
let reg3=new RegExp('a|c+');
let reg4=new RegExp('a|c+','g');
or
let reg4=new RegExp(/a|c+/,'g');
~~~
### 3. 典型例題
>[info] 題1:詳解 exec 函數
~~~
var myRe = /\d+/g;
var myArray = myRe.exec("asd123ree3ffg56");
首次執行得到:
~~~

`再次執行 myRe.exec('asd123ree3ffg56'),直到搜索到字符串末尾也未能匹配,則返回 null`

`如果沒有全局修飾符,那么久永遠是從頭開始匹配`

>[success] 定義正則中間變量的作用
~~~
如果沒有定義 myRe 來作為變量保存,而是直接用正則字面量的形式去執行函數,那么我們就沒法去取的,
匹配指針所在的位置 .lastIndex,正則字面量 .source
~~~
>[info]題2: 使用 `replace()` 方法來轉換字符串中的單詞。
在匹配到的替換文本中,腳本使用替代的 `$1,$2` 表示第一個和第二個括號的子字符串匹配。
~~~
var re = /(\w+)\s(\w+)/;
var str = 'John Smith';
var newstr = str.replace(re, '$2, $1');
console.log(newstr);
這個表達式輸出 'Smith, John'。
~~~
>[info]題3:使用 `match` 找出字符串中符合的量

>[info]題4:字符串的 `split` 方法

>[info]題5:驗證郵箱的正則
~~~
// 如果是郵箱就返回 true,否則返回 false
function isEmail(s) {
return /\w+@\w+\.com/.test(s);
}
~~~
>[info]題6: 輸入正確的16進制的顏色值返回 `RGB` 形式,如果輸入的形式不正確直接返回 `'invalid'`
~~~
function toRGB(s) {
let reg=/^#(?:[0-9a-fA-f]{3}){1,2}$/,
array0,
array1,
array2;
if(!reg.test(s)) { //如果不否和形式直接返回
return 'invalid';
} else {
// 去除掉#
array0=Array.prototype.slice.call(s).splice(1);
if(array0.length===3) {
array1=[
array0[0].toString()+array0[0].toString(),
array0[1].toString()+array0[1].toString(),
array0[2].toString()+array0[2].toString()
]
} else {
array1=[
array0[0].toString()+array0[1].toString(),
array0[2].toString()+array0[3].toString(),
array0[4].toString()+array0[5].toString()
]
}
array2=array1.map(function(value) {
return parseInt(value,16);
});
// 16進制數轉化為10進制數
return 'RGB('+array2.toString()+')';
}
}
~~~

### 4. 修飾符
| 符號 | 描述 |
| --- | --- |
| `g` | 全局搜索。 |
| `i` | 不區分大小寫搜索。 |
| `m` | 多行搜索 |
| `y` | 執行“粘性”搜索,匹配從目標字符串的當前位置開始,可以使用 y 標志。 |
* * * * *
### 5. 特殊字符
* * * * *
~~~
\
\w 這種在普通字符串前面加反斜杠,使之變成有特殊意義的字符;
本來 *,+,? 等是特殊意義字符,加了反斜杠取消了特殊性,表示普通字符;
在字符串中,反斜杠本身就是特殊字符,所以需要先轉義
~~~

~~~
^
匹配字符串的開始
(如果多行標志為 `true` 是,那么也匹配換行符后緊跟的位置)
~~~


~~~
$
匹配輸入的結束。如果多行標示被設置為 true,那么也匹配換行符前的位置。
* 匹配一個表達式0次或多次,等價于{0,}
+ 匹配一個表達式1次或多次,等價于{1,}
?
匹配一個表達式 0 次或 1 次,等價于 {0,1}
例如,/e?le?/ 匹配 'angel' 中的 'el',和 'angle' 中的 'le' 以及 'oslo' 中的 'l' 。
如果緊跟在任何量詞 *、 +、? 或 {} 的后面,將會使量詞變為非貪婪的(匹配盡量少的字符),和缺省使用的貪婪模式(匹配盡可能多的字符)正好相反。
例如,對 '123abc' 應用 /\d+/ 將會返回 '123',如果使用 /\d+?/,那么就只會匹配到 '1'。
.
(小數點)匹配除換行符之外的任何單個字符。
~~~

~~~
(x)
匹配 'x' 并且記住匹配項,就像下面的例子展示的那樣。括號被稱為 捕獲括號。
模式 /(foo) (bar) \1 \2/ 中的'(foo)' 和 '(bar)' 匹配并記住字符串 'foo bar foo bar' 中前兩個單詞。模式中的 \1 和 \2 匹配字符串的后兩個單詞。
注意 \1、\2、\n 是用在正則表達式的匹配環節。
在正則表達式的替換環節,則要使用像 $1、$2、$n 這樣的語法,例如,'bar foo'.replace( /(...) (...)/, '$2 $1' )。
~~~

~~~
(?:x)
匹配 'x' 但是不記住匹配項。這種叫作非捕獲括號。在匹配規則上與上面的一樣。
x(?=y)
匹配'x'僅僅當'x'后面跟著'y'.這種叫做正向肯定查找。
x(!=y)
匹配'x'僅僅當'x'后面跟著'y'.這種叫做正向否定查找。
x(?!y)
匹配'x'僅僅當'x'后面不跟著'y',這個叫做正向否定查找。
x|y
匹配‘x’或者‘y’。
{n}
n是一個正整數,匹配了前面一個字符剛好發生了n次。
{n,m}
n 和 m 都是整數。匹配前面的字符至少n次,最多m次。如果 n 或者 m 的值是0, 這個值被忽略。
[xyz]
一個字符集合。匹配方括號的中任意字符,包括轉義序列。你可以使用破折號(-)來指定一個字符范圍。
對于點(.)和星號(*)這樣的特殊符號在一個字符集中沒有特殊的意義。他們不必進行轉義,不過轉義也是起作用的。
[^xyz]
一個反字符集。也就是說不匹配任何出現在字符集中的字符
\b
匹配一個詞的邊界。一個詞的邊界就是一個詞不被另外一個詞跟隨的位置或者不是另一個詞匯字符前邊的位置。
注意,一個匹配的詞的邊界并不包含在匹配的內容中。換句話說,一個匹配的詞的邊界的內容的長度是0。
\B
匹配一個非單詞邊界。他匹配一個前后字符都是相同類型的位置:都是單詞或者都不是單詞。一個字符串的開始和結尾都被認為是非單詞。
例如,/\B../匹配'noonday'中得'oo', 而/y\B./匹配'possibly yesterday'中得 'ye'
\d
匹配一個數字。等價于[0-9]。
\D
匹配一個非數字字符。
等價于[^0-9]。
\n
匹配一個換行符 (U+000A)。
\r
匹配一個回車符 (U+000D)。
\f
匹配一個換頁符 (U+000C)。
\s
匹配一個空白字符,包括空格、制表符、換頁符和換行符。
\S
匹配一個非空白字符。
\w
匹配一個單字字符(字母、數字或者下劃線)。
等價于[A-Za-z0-9_]。
\W
匹配一個非單字字符。
等價于[^A-Za-z0-9_]。
\0
匹配 NULL (U+0000) 字符
~~~
* * * * *