RegExp对象
Js 中通过内置 RegExp 对象来支持正则表达式
通过以下两种来实例化 RegExp 对象:
字面量
构造函数
字面量
1 | e.g. |
构造函数
1 | e.g. |
修饰符
g: global 全文搜索 若不添加 匹配到第一个就结束i: ignore case 忽略大小写 默认大小写敏感m: multiple lines 多行搜索
元字符
js 中由两种基本的字符类型组成:
原义文本字符
元字符
元字符是在正则表达式中有特殊含义的非字母字符
例如: *,^,+,?,$,.,|,\,(),{},[]等
字符类
一般情况下 正则表达式一个字符对应字符串的一个字符
可使用 [] 来构建一个简单的类
所谓类就是符合某种特征的对象 一个泛指 而不是特指某个字符
表达式 [abc] 把字符 a 或 b 或 c 归为一类 表达式可匹配这类的字符
1 | e.g. |
字符类取反
通常使用 元字符 ^ 来创建一个 反向类/负向类
反向类 是指不属于某个类的内容
表达式 [^abc] 表示不是 a 或 b 或 c 的内容
1 | e.g. |
范围类
正则表达式还提供了 范围类
可使用 [a-z] 来连接两个字符来表示 从 a 到 z 的任意字符
这是一个闭区间 包含 a 和 z 本身
在 [] 组成的类内部是可以连写的 例如: [a-zA-Z]
1 | e.g. |
JS预定义类及边界
正则表达式提供了 预定义类 来匹配常见的字符类
| 字符 | 等价类 | 含义 |
|---|---|---|
| . | [^\r\n] | 除了回车符和换行符之外的所有字符 |
| \d | [0-9] | 数字字符 |
| \D | [^0-9] | 非数字字符 |
| \s | [\t\n\x0B\f\r] | 空白符 |
| \S | [^\t\n\x0B\f\r] | 非空白符 |
| \w | [a-zA-Z_0-9] | 单词字符(字母数字下划线) |
| \W | [^a-zA-Z_0-9] | 非单词字符 |
d: digit
s: space
w: word
大写字母表取反
例子:匹配一个 ab + 数字 + 任意字符 的字符串
1 | e.g. |
边界
正则表达式还提供了 常用的边界匹配字符
| 字符 | 含义 |
|---|---|
| ^ | 从xxx开始 |
| $ | 从xxx结束 |
| \b | 单词边界 |
| \B | 非单词边界 |
1 | e.g |
1 | e.g |
量词
| 字符 | 含义 |
|---|---|
| ? | 出现 0 次或者一次(最多出现一次) |
| + | 出现一次或多次 (至少一次) |
| * | 出现 0 次或者多次 (任意次) |
| {n} | 出现 n 次 |
| {n,m} | 出现 n 到 m 次 |
| {n,} | 至少出现 n 次 |
1 | e.g. |
贪婪模式与非贪婪模式
贪婪模式
- 就是在匹配成功的前提下 尽可能多的去匹配
1 | e.g. |
非贪婪模式
就是在匹配成功的前提下 尽可能少的去匹配
非贪婪模式 可使用
?来表示
1 | e.g. |
分组
- 可使用
()来分组 使量词作用于分组
1 | e.g. |
或
- 可使用
|来匹配其中一个
1 | e.g. |
反向引用
- 如果出现多个分组 可使用
$来表示第几个分组
实例: 2019-09-08 替换成 09/08/2019
1 | e.g. |
忽略分组
- 不希望捕获某些分组 只需要在分组内添加
?:即可忽略分组
1 | e.g. |
前瞻
正则表达式从文本头部向文本尾部开始解析,文本尾部方向 为 “前”
前瞻 就是在正则表达式匹配规则的时候,向前检查是否符合断言(断言就是前面语法的一部分)
后顾/后瞻 方向相反
js 不支持 后瞻
符合和不符合特定的断言 称为 肯定/正向匹配 和 否定/负向匹配
| 名称 | 正则 |
|---|---|
| 正向前瞻 | exp(?= assert) |
| 负向前瞻 | exp(?! assert) |
| 正向后瞻 | js不支持 |
| 负向后瞻 | js不支持 |
正向前瞻
1 | e.g. |
反向前瞻
1 | e.g. |
对象属性
global: 是否全文搜索,默认false
ignore case: 是否大小写敏感,默认false
muliline: 多行搜索,默认false
lastIndex: 是当前正则表达式匹配内容的最后一个字符的下一个位置
source: 正则表达式的文本字符串
test 方法
RegExp.prototype.test(str)
以下的事例 出现了这样的情况
多打印几次后 从原来的 true 变成了 false
这是为什么呢?
这是因为 lastIndex 这个属性
当它下一次执行的时候 并不是从头开始匹配的
而是从匹配最后一个字符的下一个位置
也就是 第一次是匹配到 a 值为 true
第二次匹配的时候 从 a 的下一个位置
也就是 b 匹配到了 值为 true
第三次 从 b 的下一个位置 匹配
因而后面 没有可匹配的 所以值为 false
1 | e.g. |
exec 方法
RegExp.prototype.exec(str)
使用正则表达式模式对字符串执行搜索,并将更新全局的 RegExp 对象的属性以反映匹配结果
如果没有匹配的文本 则返回
null否则返回一个结果数组:index: 匹配文本的第一个位置input: 用来存放被检索的字符串string
非全局调用
调用非全局的 RegExp 的 exec() 返回一个数组
第一个元素是与正则表达式匹配的文本
第二个元素是与 RegExpObject 的第一个子表达式相匹配的文本(如果有的话)
第三个元素是与 RegExp 对象的第二个子表达式相匹配的文本(如果有的话)(也就是分组)
以此类推
以下的实例:
非全局调用的结果: 0 1 1az2,a,z
0: lastIndex 的值1: 匹配文本的第一个位置1az2: 被检索到的字符串a: 第一个分组的值 (\w)z: 第二个分组的值 (\w)
全局调用的结果:
5 1 1az2,a,z
10 6 3cy4,c,y 同理
5: 匹配最后一个字符的下一个位置(下标值) 也就是b1: 匹配文本的第一个位置(下标值)1az2: 被检索到的字符串a: 第一个分组的值 (\w)z: 第二个分组的值 (\w)
1 | e.g. |
字符串对象方法
search 方法
用于检索字符串中指定的子字符串 或者检索与正则表达式匹配的子字符串
返回 第一个匹配结果 index,查找不到则返回 -1
search 方法 不全局匹配 忽略 g 标志,总是从字符串的开始进行检索
1 | e.g. |
match 方法
用于检索字符串,以找到一个或者多个于regexp匹配的文本
有无 g 标志 差距很大
非全局调用:
match 方法只能在字符串中执行一次
如果没有找到匹配的结果 则返回 null
否则返回一个数组,其中存放了与它相匹配的文本信息
返回数组的一个元素存放的是匹配的文本,而其余的元素存放的是与正则表达式的子表达式匹配的文本
除了常规的数组元素,返回的数组还含有2个对象属性:
index 声明匹配文本的起始字符在字符串的位置
input 声明对 stringObject 的引用
1 | e.g. |
全局调用:
具有 g 标志的 match 方法将执行全局检索 找到字符串中的所有匹配子字符串
没有找到匹配的子字符串,则返回 null
如果找到了一个或者多个匹配子串,则返回一个数组
数组中存放的是字符串中所有匹配子串,而且也没有 index 或者 input 属性
1 | e.g. |
split 方法
- 把字符串分割成字符数组
1 | e.g. |
- 在一些比较复杂的分割情况下 可以使用正则表达式解决
1 | e.g. |
replace 方法
三种传值的方法:
- String.prototype.replace(str, replaceStr);
- String.prototype.replace(reg, replaceStr);
- String.prototype.replace(reg, function);
1 | e.g. |
function会在每次匹配替换的时候调用,有四个参数:
匹配字符串
正则表达式分组内容,没有分组则没有该参数(有几个分组 就有几个分组参数)
匹配项在字符串的 index
原字符串
1 | e.g. |