# 正则
正则一直在我眼里一直是一串天文符号,但是他的作用又是无可异议的大,
所以今天开始学习正则,虽犹如学习一门新语言,但冲就完事了。
# 正则表达式到底是什么
正则表达式(Regular Expression)其实就是一门工具,目的是为了字符串模式匹配,从而实现搜索和替换功能。它起源于上个 20 世纪 50 年代科学家在数学领域做的一些研究工作,后来才被引入到计算机领域中。从它的命名我们可以知道,它是一种用来描述规则的表达式。而它的底层原理也十分简单,就是使用状态机的思想进行模式匹配。
我们可以通过regexper.com/ (opens new window) 来学习状态机运行
通过regex101.com/ (opens new window)来测试你写的正则
准备好了,那就 let’s go!
# 单个字符
最简单是就是 /a/ 匹配字符串中的 a
但是有一些特殊字符 就需要搭配 **\ ** 来匹配:如下表
特殊字符 | 正则表达式 | 记忆方式 |
---|---|---|
换行符 | \n | new line |
换页符 | \f | form feed |
回车符 | \r | return |
空白符 | \s | space |
制表符 | \t | tab |
垂直制表符 | \v | vertical tab |
回退符 | [\b] | backspace,之所以使用[]符号是避免和\b 重复 |
# 多个字符
匹配集合 使用 /[123]/
每个字符都全部列出就显得很繁琐, 所以就可以使用 /[0-9]/
匹配所有数字
匹配区间 | 正则表达式 | 记忆方式 |
---|---|---|
除了换行符之外的任何字符 | . | 句号,除了句子结束符 |
单个数字, [0-9] | \d | digit |
除了[0-9] | \D | not digit |
包括下划线在内的单个字符,[A-Za-z0-9_] | \w | word |
非单字字符 | \W | not word |
匹配空白字符,包括空格、制表符、换页符和换行符 | \s | space |
匹配非空白字符 | \S | not space |
# 循环和重复匹配
匹配规则 | 元字符 | 联想方式 |
---|---|---|
0 次或 1 次 | ? | 且问,此事有还无 |
0 次或无数次 | * | 宇宙洪荒,辰宿列张:宇宙伊始,从无到有,最后星宿布满星空 |
1 次或无数次 | + | 一加, +1 |
特定次数 | {x}, {min, max} | 可以想象成一个数轴,从一个点,到一个射线再到线段。min 和 max 分别表示了左闭右闭区间的左界和右界 |
# 位置边界
边界和标志 | 正则表达式 | 记忆方式 |
---|---|---|
单词边界 | \b | boundary |
非单词边界 | \B | not boundary |
字符串开头 | ^ | 小头尖尖那么大个 |
字符串结尾 | $ | 终结者,美国科幻电影,美元符$ |
多行模式 | m 标志 | multiple of lines |
忽略大小写 | i 标志 | ignore case, case-insensitive |
全局模式 | g 标志 | global |
# 子表达式
# (?:pattern)
非获取匹配,匹配 pattern 但不获取匹配结果,不进行存储供以后使用。这在使用或字符“(|)”来组合一个模式的各个部分是很有用。例如“industr(?:y|ies)”就是一个比“industry|industries”更简略的表达式。
# (?=pattern)
非获取匹配,正向肯定预查,在任何匹配 pattern 的字符串开始处匹配查找字符串,该匹配不需要获取供以后使用。例如,“Windows(?=95|98|NT|2000)”能匹配“Windows2000”中的“Windows”,但不能匹配“Windows3.1”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
# (?!pattern)
非获取匹配,正向否定预查,在任何不匹配 pattern 的字符串开始处匹配查找字符串,该匹配不需要获取供以后使用。例如“Windows(?!95|98|NT|2000)”能匹配“Windows3.1”中的“Windows”,但不能匹配“Windows2000”中的“Windows”。
# (?<=pattern)
非获取匹配,反向肯定预查,与正向肯定预查类似,只是方向相反。例如,“(?<=95|98|NT|2000)Windows”能匹配“2000Windows”中的“Windows”,但不能匹配“3.1Windows”中的“Windows”。
# (?<!pattern)
非获取匹配,反向否定预查,与正向否定预查类似,只是方向相反。例如“(?<!95|98|NT|2000)Windows”能匹配“3.1Windows”中的“Windows”,但不能匹配“2000Windows”中的“Windows”。这个地方不正确,有问题
回溯查找 | 正则 | 记忆方式 |
---|---|---|
引用 | \0,\1,\2 和 $0, $1, $2 | 转义+数字 |
非捕获组 | (?😃 | 引用表达式(()), 本身不被消费(?),引用(😃 |
前向查找 | (?=) | 引用子表达式(()),本身不被消费(?), 正向的查找(=) |
前向负查找 | (?!) | 引用子表达式(()),本身不被消费(?), 负向的查找(!) |
后向查找 | (?<=) | 引用子表达式(()),本身不被消费(?), 后向的(<,开口往后),正的查找(=) |
后向负查找 | (?<!) | 引用子表达式(()),本身不被消费(?), 后向的(<,开口往后),负的查找(!) |
# JS 方法
# replace() 方法
//regexp 必需。规定子字符串或要替换的模式的 RegExp 对象。
//replacement 必需。一个字符串值。规定了替换文本或生成替换文本的函数。
stringObject.replace(regexp/substr,replacement)
replacement 可以是字符串,也可以是函数。如果它是字符串,那么每个匹配都将由字符串替换。但是 replacement 中的 $ 字符具有特定的含义。
字符 | 替换文本 |
---|---|
$1、$2、...、$99 | 与 regexp 中的第 1 到第 99 个子表达式相匹配的文本。 |
$& | 与 regexp 相匹配的子串。 |
$` | 位于匹配子串左侧的文本。 |
$' | 位于匹配子串右侧的文本。 |
$$ | 直接量符号。 |
# match() 方法
# 用法
match() 方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。
该方法类似 indexOf() 和 lastIndexOf(),但是它返回指定的值,而不是字符串的位置。