正则
基础介绍
基础介绍就不多赘述了,都是来自菜鸟教程:https://www.runoob.com/jsref/jsref-obj-regexp.html 里面的内容
基础语法
-
构造函数
语法:
参数1:表达式,且需要注意的是对于一些\w
等需要通过反斜杠进行转义
参数2:修饰符,i g mvar reg = new RegExp(pattern, modifiers)
示例:
var reg = new RegExp("\\w+", 'g')
-
字面量
语法:
var reg = /pattern/modifiers
示例:
var reg = /\w+/
修饰符
修饰符用于执行区分大小写和全局匹配:
修饰符 | 描述 |
---|---|
i | 执行对大小写不敏感的匹配。 |
g | 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。 |
m | 执行多行匹配。 |
方括号
方括号用于查找某个范围内的字符:
表达式 | 描述 |
---|---|
[abc] | 查找方括号之间的任何字符。 |
[^abc] | 查找任何不在方括号之间的字符。 |
[0-9] | 查找任何从 0 至 9 的数字。 |
[a-z] | 查找任何从小写 a 到小写 z 的字符。 |
[A-Z] | 查找任何从大写 A 到大写 Z 的字符。 |
[A-z] | 查找任何从大写 A 到小写 z 的字符。 |
[adgk] | 查找给定集合内的任何字符。 |
[^adgk] | 查找给定集合外的任何字符。 |
(red|blue|green) | 查找任何指定的选项。 |
元字符
元字符(Metacharacter)是拥有特殊含义的字符
元字符 | 描述 |
---|---|
. | 查找单个字符,除了换行和行结束符。 |
\w | 查找数字、字母及下划线。 |
\W | 查找非单词字符。 |
\d | 查找数字。 |
\D | 查找非数字字符。 |
\s | 查找空白字符。 |
\S | 查找非空白字符。 |
\b | 匹配单词边界。 |
\B | 匹配非单词边界。 |
\0 | 查找 NULL 字符。 |
\n | 查找换行符。 |
\f | 查找换页符。 |
\r | 查找回车符。 |
\t | 查找制表符。 |
\v | 查找垂直制表符。 |
\xxx | 查找以八进制数 xxx 规定的字符。 |
\xdd | 查找以十六进制数 dd 规定的字符。 |
\uxxxx | 查找以十六进制数 xxxx 规定的 Unicode 字符。 |
量词
量词 | 描述 |
---|---|
n+ | 匹配任何包含至少一个 n 的字符串。例如,/a+/ 匹配 “candy” 中的 “a”,“caaaaaaandy” 中所有的 “a”。 |
n* | 匹配任何包含零个或多个 n 的字符串。例如,/bo*/ 匹配 “A ghost booooed” 中的 “boooo”,“A bird warbled” 中的 “b”,但是不匹配 “A goat grunted”。 |
n? | 匹配任何包含零个或一个 n 的字符串。例如,/e?le?/ 匹配 “angel” 中的 “el”,“angle” 中的 “le”。 |
n{X} | 匹配包含 X 个 n 的序列的字符串。例如,/a{2}/ 不匹配 “candy,” 中的 “a”,但是匹配 “caandy,” 中的两个 “a”,且匹配 “caaandy.” 中的前两个 “a”。 |
n{X,} | X 是一个正整数。前面的模式 n 连续出现至少 X 次时匹配。例如,/a{2,}/ 不匹配 “candy” 中的 “a”,但是匹配 “caandy” 和 “caaaaaaandy.” 中所有的 “a”。 |
n{X,Y} | X 和 Y 为正整数。前面的模式 n 连续出现至少 X 次,至多 Y 次时匹配。例如,/a{1,3}/ 不匹配 “cndy”,匹配 “candy,” 中的 “a”,“caandy,” 中的两个 “a”,匹配 “caaaaaaandy” 中的前面三个 “a”。注意,当匹配 “caaaaaaandy” 时,即使原始字符串拥有更多的 “a”,匹配项也是 “aaa”。 |
n$ | 匹配任何结尾为 n 的字符串。 |
^n | 匹配任何开头为 n 的字符串。 |
?=n | 匹配任何其后紧接指定字符串 n 的字符串。 |
?!n | 匹配任何其后没有紧接指定字符串 n 的字符串。 |
贪婪匹配与惰性匹配
贪婪匹配,贪婪,简单理解为就是有多少个我就匹配多少个,尽可能的匹配更多个
惰性匹配,懒惰,简单理解为就是不管有多少个,我就匹配最少最小的那个,其他的懒得匹配了
贪婪匹配
let reg = /\d{2,5}/g
let str = '123 1234 12345 123456'
str.match(reg)
惰性匹配
let reg = /\d{2,5}?/g
let str = '123 1234 12345 123456'
str.match(reg)
通过对比我们发现,贪婪匹配
与惰性匹配
之间也就是相差了一个?
,也就是说在量词符后面加个?
就是我们说的惰性匹配了
贪婪匹配 | 惰性匹配 |
---|---|
n+ | n+? |
n* | n*? |
n? | n?? |
n{X} | n{X}? |
n{X,} | n{X,}? |
n{X,Y} | n{X,Y}? |
方法
基础方法
方法 | 描述 |
---|---|
exec | 检索字符串中指定的值。返回找到的值,并确定其位置。 |
test | 检索字符串中指定的值。返回 true 或 false。 |
toString | 返回正则表达式的字符串。 |
支持正则表达式的 String 对象的方法
方法 | 描述 | FF | IE |
---|---|---|---|
search | 检索与正则表达式相匹配的值。 | 1 | 4 |
match | 找到一个或多个正则表达式的匹配。 | 1 | 4 |
replace | 替换与正则表达式匹配的子串。 | 1 | 4 |
split | 把字符串分割为字符串数组。 |
位置匹配符
这里将一些模糊点着重说明一下
^
这个大家都很熟悉,匹配开始位置
'aa11..AA22'.replace(/^/, '😜')
$
这个大家也很熟悉,匹配结束位置
'aa11..AA22'.replace(/$/, '😜')
\b
匹配边界位置
什么是边界???
就正则而言:边界就是不同的元字符类型或者指定字符的拼接处
可能还是有点不是很好理解,直接用示例说话,相信就容易理解的多了
- 示例
'aa11..AA22'.replace(/\b/g, '😜')
- 示例
'aa11..AA22'.replace(/\b./g, '😜')
说明:.
代表的是单个字符,\b.
则就表示的是单个字符且处在边界位置的,边界位置在前,单个字符在后
- 示例
'aa11..AA22'.replace(/\b../g, '😜')
说明:同理,\b..
则就表示的是两个单个字符且处在边界位置的,边界位置在前,两个单个字符在后
- 示例
'aa11..AA22'.replace(/..\b/g, '😜')
说明:同理,..\b
则就表示的是两个单个字符且处在边界位置的,边界位置在后,两个单个字符在前
- 示例
'aa11..AA22'.replace(/\bAA/g, '😜')
?=
正向先行断言
?=n
:匹配任何其后紧接
指定字符串 n 的字符串,通俗一点说就是匹配有
字符串 n前面
的那个位置
- 示例
'aa11..AA22'.replace(/(?=a1)/g, '😜')
说明:?=a1
,找到a1
字符串所在位置的前面
?!
负向先行断言
?!n
:匹配任何其后没有紧接
指定字符串 n 的字符串,通俗一点说就是匹配没有
字符串 n前面
的那个位置
与
?=
对比,可以理解为?=n
匹配到的位置之外的位置都是属于?!n
的
- 示例
'aa11..AA22'.replace(/(?!a1)/g, '😜')
?<=
?<=n
:匹配任何其前紧接
指定字符串 n 的字符串,通俗一点说就是匹配有
字符串 n后面
的那个位置
- 示例
'aa11..AA22'.replace(/(?<=a1)/g, '😜')
?<!
?<!n
:匹配任何其前没有紧接
指定字符串 n 的字符串,通俗一点说就是匹配没有
字符串 n后面
的那个位置
- 示例
'aa11..AA22'.replace(/(?<!a1)/g, '😜')
分支符
|
可以理解为 或者的意思,以|
为分界线,只要符合|
左边或者右边的任意一个字符规则的即为匹配
let reg = /good|nice/g
let str = 'good idea, nice try.' // 都有
console.log(reg.test(str))
// true
let reg = /good|nice/g
let str = 'god idea, nice try.' // 只有其中一个nice
console.log(reg.test(str))
// true
let reg = /good|nice/g
let str = 'god idea, nce try.' // 都没有
console.log(reg.test(str))
// false
小括号() ------ 另一个说法:子表达式
()
的作用可以理解为给括号内的字符形成一个整体,另一个说法说成括号内的为一个子表达式
()
可以分成捕获性括号与非捕获性括号,这里说明一下什么是捕获???
捕获:我们用正则
()
去匹配字符串,一般来说会匹配上对应规则的字符串,另外就还有()
对应分组1、分组2、分组3……,通常称之为捕获组,这些个()
对应的就是捕获到的字符串的分组字符串。
捕获性括号 ()
(X)
:匹配X,并捕获匹配项。
非捕获性括号 (?😃
(?:X)
:匹配X,但是不捕获匹配项。非捕获组,它跟普通的括号 () 的区别在于,它不会保存匹配到的内容,但是它仍然会消耗字符并返回匹配内容,只是不会保存匹配结果。
首先,先说明一下: 正则replace
方法:第一个参数代表的是该正则匹配的字符串,倒数第二个参数为匹配的字符串在原字符串中初始出现的索引位置,倒数第一个参数为原字符串,而在它们之间的参数则分别代表的是正则中的分组(也就是圆括号)中所捕获的字符串。
https://www.runoob.com/jsref/jsref-replace.html,最下面的笔记有说明
也可参考一下我之前写的另一篇博客JavaScript 之 replace() 方法的第二个参数为匿名函数时的理解(涉及正则)
- 捕获性括号
案例1
"hello---JavaScript666".replace(/(JavaScript(\d+))/g, "$2")
// 'hello---666'
这种写法可能不那么好理解,那么换成下面那种写法看下
案例2
"hello---JavaScript666".replace(/(JavaScript(\d+))/g,(a, a1, a2, a3) => {
console.log(a, a1, a2, a3) // JavaScript666 JavaScript666 666 8
})
是不是就好理解了一点,$2
对应的就是括号捕获的内容的值,但是$2
对应的是第二个括号捕获的值,第一个括号内匹配的字符串还是JavaScript666
,因为用的是捕获性括号,所以捕获这个字符串也是JavaScript666
,第二个括号(\d+)
是捕获性括号,匹配的是数字,捕获的是666
- 非捕获性括号
案例3
"hello---JavaScript666".replace(/(?:JavaScript(\d+))/g, "$1")
// 'hello---666'
这种写法可能不那么好理解,那么换成下面那种写法看下
案例4
"hello---JavaScript666".replace(/(?:JavaScript(\d+))/g,(a, a1, a2, a3) => {
console.log(a, a1, a2, a3) // JavaScript666 666 8 hello---JavaScript666
})
是不是就好理解了一点,$1
对应的就是括号捕获的内容的值,第一个括号内匹配的字符串还是JavaScript666
,因为用了非捕获性括号,所以不捕获这个字符串,第二个括号(\d+)
是捕获性括号,匹配的是数字;
案例5
"hello world".replace(/(?:hello) (world)/,"$1") // 匹配内容为hello world,但是hello并没有被保存,因此$1取的是world,故结果为world
匹配内容为hello world,但是hello并没有被保存,因此$1取的是world,故结果为world
小结一下:
"hello---JavaScript666".replace(/(?:JavaScript(\d+))/g, "$1")
,这种写法的$1
,对应的是第一个捕获性括号,$2
对应的是第二个捕获性括号,以此类推