创建一个正则表达式
方法一:使用正则表达式字面量
- 示例: const reg = /正则表达式/匹配模式
方法二:调用 RegExp 对象的构造函数
- 示例:const reg = new RegExp(“正则表达式”,”匹配模式(可选)”)
- 注:使用 typeof 检查正则对象,会返回 object
匹配模式
i
:忽略大小写g
:全局匹配模式m
:多行匹配,使边界字符 ^ 和 $ 匹配每一行的开头和结尾s
:(es2018)匹配单个字符,与.一起使用,使.代表一切字符,称为 dotAll 模式- 使用 reg.dotAll 来判断该正则表达式是否处于动 dotAll 模式
正则表达式规则
^
:匹配开头$
:匹配结尾\w
:匹配任意字母、数字、_ == [A-z0-9_]\W
:匹配除了字母、数字、_ == [^A-z0-9_]\d
:匹配任意的数字 == [0-9]\D
:匹配除了数字 == [^0-9]\s
:匹配空格\S
:匹配除了空格\b
:单词边界(在单词两边使用,表示在这个字符串中完整匹配这个单词)\B
:匹配除了单词边界[a-z]
:任意小写字母[A-Z]
:任意大写字母[A-z]
:任意字母[0-9]
:任意数字[ ]
:匹配括号内的任意一个字符。[^ ]
:匹配除了括号内的字符以外的任意一个字符
量词 — 只对它前边的一个内容起作用
{n}
:正好出现 n 次{m,n}
:出现 m-n 次{m,}
:m 次以上+
:至少一个 == {1,}*
:0 个或多个 == {0,}?
:0 个或 1 个 == {0,1}.
:表示任意字符(除了换行符)- 注:
*、+
都是贪婪的,会尽可能匹配更多的文字
,在它们后面加上?
就可以实现非贪婪或最小匹配
特殊字符
\
: 转义字符,用于匹配特殊字符本身|
:用于指定多个模式的选择( )
:用于分组和捕获子表达式(?: )</span>
:用于分组但不捕获子表达式?=
:exp1(?=exp2):查找 exp2 前面的 exp1,即先行断言
?<=
:(?<=exp2)exp1:查找 exp2 后面的 exp1,即后行断言
,es2018?!
:exp1(?!exp2):查找后面不是 exp2 的 exp1,即先行否定断言
?<!
:exp1(?<!exp2):查找前面不是 exp2 的 exp1,即后行否定断言
,es2018\1
:指定第一个子匹配项。
1 | eg1:去除开头的空格 |
常见的匹配规则
- 匹配 HTML 标记 —
<[a-zA-Z]+.*?>([\s\S]*?)</[a-zA-Z]*?>
- 匹配空行 —
/^\s*$/
- 一个单词连续出现的位置 —
/\b([a-z]+) \1\b/gi
- 匹配一个 URL 解析为协议、域、端口及相对路径 —
/(\w+):\/\/([^/:]+)(:\d*)?([^# ]*)/
- 定位章节的位置 —
/^(?:Chapter|Section) [1-9][0-9]{0,1}$/
合法手机号
- 手机号的规则:
- 以 1 开头
- 第二位 3-9 任意数字
- 三位以后任意数字 9 个
- 匹配模式:
/^1[3-9][0-9]{9}$/
邮箱
- 邮件的规则:
- 前边可以是任意字符
- 跟着一个@
- 后边可以是任意字符
- 后面是.com | .cn 等
- 匹配模式:
[\w.%+-]+@[\w.-]+(\.[A-z]{2,5}){1,2}$
字符串的正则方法
1 | const string = 'test1test2test3' |
match()
- 从字符串中将符合正则表达式规则的内容中,返回数组或 null
- 默认,仅返回第一个匹配的结果 == exec()方法
- 使用全局匹配模式 g,返回与完整正则表达式匹配的所有结果 == matchAll()
test()
- 用来查看正则表达式与指定的字符串是否匹配,返回 true 或 false
search()
- 可以搜索字符串中是否含有指定内容,返回索引值
- 如果搜索到指定内容,则会返回第一次出现的索引,如果没有搜索到返回-1
- 注:serach()只会查找第一个,即使设置全局匹配也没用
replace()
- 可以将字符串中指定内容替换为新的内容,返回字符串
- 参数:
- 被替换的内容,可以接受一个正则表达式作为参数
- 新的内容
split()
- 可以将一个字符串拆分为一个数组
- 如果传递一个空串作为参数,则会将每个字符都拆分为数组中的一个元素
修饰符
U 修饰符
- es6 新增,末尾加 u,代表 Unicode 模式(正确识别码点大于 0xFFFF 的 Unicode 字符)
i 修饰符 + u 修饰符
- 可以识别非规范的 K 字符
点字符 + u 修饰符
- 识别码点大于 0xFFFF 的 Unicode 字符
使用大括号表示 Unicode 字符,在正则表达式中必须加上 u 修饰符,否则大括号内容识别成量词
- 示例:/\u{61}/u.test(‘a’) // true
使用 u 修饰符,量词会正确识别 Unicode 字符
/^\S$/u.test(‘𠮷’)
- /S 匹配所有非空白字符,加了 u,能正确匹配码点大于 0xFFFF 的 Unicode 字符
RegExp.prototype.unicode 属性
- 判断是否加了 u 修饰符
y修饰符
全局匹配
,后一次匹配都从上一次匹配成功的下一个位置开始[必须从剩余的第一个位置开始
]- reg.lastIndex — 指定从那个位置开始匹配,但
必须从这个位置发现匹配
- reg.sticky — 表示是否设置了 y 修饰符。
- reg.flags — 返回正则表达式的修饰符
示例:
1 | const s = 'aaa_aa_a' |
修饰符 g 与修饰符 y 区别:
- g:可以在剩余的位置中只要找到对应的内容,就匹配返回
- y:必须从剩余第一位匹配,如果第一位不是就返回 null
v 修饰符:属性类的运算
- 前提: 正则表达式必须使用 v 修饰符。
- 差集运算(A 减去 B):[A–B]
- 交集运算(A 与 B 的交集):[A&&B]
- 示例:[\p{Decimal_Number}–[0-9]] // 十进制去除 ASCII 码的 0 到 9
d修饰符: 正则匹配索引
- 让
exec()
、match()
的返回结果添加indices
属性,在该属性上可以拿到匹配的开始位置
和结束位置
- 注:开始位置包含在匹配结果之中,相当于匹配结果的第一个字符的位置。但是,结束位置不包含在匹配结果之中,是匹配结果的下一个字符。
- 让
1 | const text = 'zabbcdef' |
Unicode 属性类
- 默认是
\u{…}
- es2018,
\p{…}
:匹配满足条件的所有字符。(加上 u 修饰符) - es2018,
\P{…}
:是\p{…}
的反向匹配
,即匹配不满足条件的所有字符。(加上 u 修饰符) - 标准形式:
- \p{UnicodePropertyName=UnicodePropertyValue}
- 可以只写属性名或属性值
- 示例:
1 | // \p{Number}匹配所有数组,包括罗马数字。 |
具名组匹配
- 在
圆括号内部
,模式的头部添加“问号 + 尖括号 + 组名”
,如?<组名>
- 然后在
exec方法
返回结果的groups
属性上引用该组名。 数字序号
引用(matchObj[1])依然有效
。- 如果具名组
没有匹配
,那么对应的groups
对象属性会是undefined
,但键名
再 groups 始终存在
。 - 在正则表达式内部引用某个“具名组匹配”,可以使用\k<组名>的写法
- 示例:
1 | const RE_DATE = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/ |
解构赋值和替换
- 字符串替换时,使用$<组名>引用具名组。
- 示例:
- let re = /(?
\d{4})-(? \d{2})-(? \d{2})/u; - ‘2015-01-02’.replace(re, ‘$
/$ /$ ‘)
- let re = /(?
遍历器转为数组
- 方法一:[…string.matchAll(regex)]
- 方法二:Array.from(string.matchAll(regex))