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
: 匹配最后一个字符的下一个位置(下标值) 也就是b
1
: 匹配文本的第一个位置(下标值)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. |