[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");
首次执行得到:
~~~
![](https://box.kancloud.cn/b1eedb7b80832083e65c116b7c3c2f37_465x317.png)
`再次执行 myRe.exec('asd123ree3ffg56'),直到搜索到字符串末尾也未能匹配,则返回 null`
![](https://box.kancloud.cn/cb2f6bb2708cfbecd7710dbb8c451289_331x236.png)
`如果没有全局修饰符,那么久永远是从头开始匹配`
![](https://box.kancloud.cn/1ac5b6096345453c2825460149b13de5_488x211.png)
>[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` 找出字符串中符合的量
![](https://box.kancloud.cn/097f9727cc3adf48281c34424ce267d5_476x284.png)
>[info]题4:字符串的 `split` 方法
![](https://box.kancloud.cn/715c0ab2950b36c5f5eda4a481fcad12_264x154.png)
>[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()+')';
}
}
~~~
![](https://box.kancloud.cn/8f3bf801e41ef5f605b70527cabe7f8c_232x233.png)
### 4. 修饰符
| 符号 | 描述 |
| --- | --- |
| `g` | 全局搜索。 |
| `i` | 不区分大小写搜索。 |
| `m` | 多行搜索 |
| `y` | 执行“粘性”搜索,匹配从目标字符串的当前位置开始,可以使用 y 标志。 |
* * * * *
### 5. 特殊字符
* * * * *
~~~
\
\w 这种在普通字符串前面加反斜杠,使之变成有特殊意义的字符;
本来 *,+,? 等是特殊意义字符,加了反斜杠取消了特殊性,表示普通字符;
在字符串中,反斜杠本身就是特殊字符,所以需要先转义
~~~
![](https://box.kancloud.cn/fa74599a181df73dc645ffb08843f7d0_176x50.png)
~~~
^
匹配字符串的开始
(如果多行标志为 `true` 是,那么也匹配换行符后紧跟的位置)
~~~
![](https://box.kancloud.cn/d43e2fe4099d4774e07dab7fb1ff6ab9_173x98.png)
![](https://box.kancloud.cn/c7199990a329529d2b87102ddf564bb5_194x100.png)
~~~
$
匹配输入的结束。如果多行标示被设置为 true,那么也匹配换行符前的位置。
* 匹配一个表达式0次或多次,等价于{0,}
+ 匹配一个表达式1次或多次,等价于{1,}
?
匹配一个表达式 0 次或 1 次,等价于 {0,1}
例如,/e?le?/ 匹配 'angel' 中的 'el',和 'angle' 中的 'le' 以及 'oslo' 中的 'l' 。
如果紧跟在任何量词 *、 +、? 或 {} 的后面,将会使量词变为非贪婪的(匹配尽量少的字符),和缺省使用的贪婪模式(匹配尽可能多的字符)正好相反。
例如,对 '123abc' 应用 /\d+/ 将会返回 '123',如果使用 /\d+?/,那么就只会匹配到 '1'。
.
(小数点)匹配除换行符之外的任何单个字符。
~~~
![](https://box.kancloud.cn/17ea3e00e39b4f3b39dceba885022c3c_153x149.png)
~~~
(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' )。
~~~
![](https://box.kancloud.cn/237b127a1e2bba50fd51c7b535cbdceb_399x95.png)
~~~
(?: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) 字符
~~~
* * * * *