Hello World

吞风吻雨葬落日 欺山赶海踏雪径

0%

正则表达式

正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。

给定一个正则表达式和另一个字符串,我们可以达到如下的目的:

  • 匹配 - 给定的字符串是否符合正则表达式的过滤逻辑
  • 提取 - 可以通过正则表达式,从字符串中获取我们想要的特定部分

元字符

特殊字符

^

匹配输入字符串开始的位置。如果设置了 RegExp 对象的 Multiline 属性,^ 还会与 \n 或 \r 之后的位置匹配。
要匹配 ^ 字符本身,请使用 ^。

$

匹配输入字符串结尾的位置。如果设置了 RegExp 对象的 Multiline 属性,$ 还会与 \n 或 \r 之前的位置匹配。
要匹配 $ 字符本身,请使用 $。

( )

标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 ( 和 )。

.

匹配除换行符 \n 之外的任何单字符。要匹配 . ,请使用 . 。

*

匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 *。

+

匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 +。

?

匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 ?。

|

指明两项之间的一个选择。要匹配 |,请使用 |。

\

将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, ‘n’ 匹配字符 ‘n’。’\n’ 匹配换行符。序列 ‘\‘ 匹配 “",而 ‘(‘ 则匹配 “(“。

\w

匹配字母,数字,下划线。例如要匹配”a2345BCD__TTz” 正则:”\w+” 这里的”+”字符为一个量词指重复的次数

\d

匹配数字,要匹配一个固定格式的电话号码以0开头前4位后7位,如0737-5686123 正则:^0\d\d\d-\d\d\d\d\d\d\d$

\n

匹配一个换行符。等价于 \x0a 和 \cJ。

\r

匹配一个回车符。等价于 \x0d 和 \cM。

\s

匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。注意 Unicode 正则表达式会匹配全角空格符。

\t

匹配一个制表符。等价于 \x09 和 \cI。

[]

字符组,匹配包含括号内元素的字符

{n}

n 是一个非负整数。匹配确定的 n 次。例如,’o{2}’ 不能匹配 “Bob” 中的 ‘o’,但是能匹配 “food” 中的两个 o。

{n,}

n 是一个非负整数。至少匹配n 次。例如,’o{2,}’ 不能匹配 “Bob” 中的 ‘o’,但能匹配 “foooood” 中的所有 o。’o{1,}’ 等价于 ‘o+’。’o{0,}’ 则等价于 ‘o*’。

{n,m}

m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,”o{1,3}” 将匹配 “fooooood” 中的前三个 o。’o{0,1}’ 等价于 ‘o?’。请注意在逗号和两个数之间不能有空格。

几种反义

“\W” 匹配任意不是字母,数字,下划线 的字符

“\S” 匹配任意不是空白符的字符

“\D” 匹配任意非数字的字符

“\B” 匹配不是单词开头或结束的位置

“[^abc]” 匹配除了abc以外的任意字符

量词

先解释关于量词所涉及到的重要的三个概念

贪婪(贪心)

如”*”字符 贪婪量词会首先匹配整个字符串,尝试匹配时,它会选定尽可能多的内容,如果失败则回退一个字符,然后再次尝试回退的过程就叫做回溯,它会每次回退一个字符,直到找到匹配的内容或者没有字符可以回退。相比下面两种贪婪量词对资源的消耗是最大的。

懒惰(勉强)

如 “?” 懒惰量词使用另一种方式匹配,它从目标的起始位置开始尝试匹配,每次检查一个字符,并寻找它要匹配的内容,如此循环直到字符结尾处。

占有

如”+” 占有量词会覆盖事个目标字符串,然后尝试寻找匹配内容,但它只尝试一次,不会回溯,就好比先抓一把石头,然后从石头中挑出黄金。

“*”(贪婪)

重复零次或更多。
例如”aaaaaaaa” 匹配字符串中所有的a 正则: “a*” 会出到所有的字符”a”

“+”(懒惰)

重复一次或更多次。例如”aaaaaaaa” 匹配字符串中所有的a 正则: “a+” 会取到字符中所有的a字符, “a+”与”a*”不同在于”+”至少是一次而”*” 可以是0次。

“?”(占有)

重复零次或一次。例如”aaaaaaaa” 匹配字符串中的a 正则 : “a?” 只会匹配一次,也就是结果只是单个字符a

“{n}”

重复n次。例如从”aaaaaaaa” 匹配字符串的a 并重复3次 正则: “a{3}” 结果就是取到3个a字符 “aaa”;

“{n,m}”

重复n到m次。例如正则 “a{3,4}” 将a重复匹配3次或者4次 所以供匹配的字符可以是三个”aaa”也可以是四个”aaaa” 正则都可以匹配到。

“{n,}”

重复n次或更多次。与{n,m}不同之处就在于匹配的次数将没有上限,但至少要重复n次 如 正则”a{3,}” a至少要重复3次

懒惰限定符

“*?”

重复任意次,但尽可能少重复。
如 “acbacb” 正则 “a.*?b” 只会取到第一个”acb” 原本可以全部取到但加了限定符后,只会匹配尽可能少的字符 ,而”acbacb”最少字符的结果就是”acb”。

“+?”

重复1次或更多次,但尽可能少重复。与上面一样,只是至少要重复1次。

“??”

重复0次或1次,但尽可能少重复。如 “aaacb” 正则 “a.??b” 只会取到最后的三个字符”acb”。

“{n,m}?”

重复n到m次,但尽可能少重复。如 “aaaaaaaa” 正则 “a{0,m}” 因为最少是0次所以取到结果为空。

“{n,}?”

重复n次以上,但尽可能少重复。如 “aaaaaaa” 正则 “a{1,}” 最少是1次所以取到结果为 “a”。

分组

先了解在正则中捕获分组的概念,其实就是一个括号内的内容 如 “(\d)\d” 而”(\d)” 这就是一个捕获分组,可以对捕获分组进行 后向引用 (如果后而有相同的内容则可以直接引用前面定义的捕获组,以简化表达式) 如(\d)\d\1 这里的”\1”就是对”(\d)”的后向引用。

那捕获分组有什么用呢看个例子就知道了:
如 “zery zery” 正则 \b(\w+)\b\s\1\b 所以这里的”\1”所捕获到的字符也是 与(\w+)一样的”zery”,为了让组名更有意义,组名是可以自定义名字的。

“\b(?\w+)\b\s\k\b” 用”?“就可以自定义组名了而要后向引用组时要记得写成 “\k“;自定义组名后,捕获组中匹配到的值就会保存在定义的组名里。
通常分组在替换逻辑中使用 $name 来引用(很多浏览器并不支持),也可以使用 $1来表示匹配的第一个。
比如

1
2
3
4
正则
(?<n>\*\s.*)\n\s*\n*(?<m>\w+),?
替换
$2 $1

常用语法

“(exp)”

匹配exp,并捕获文本到自动命名的组里

“(?exp)”

匹配exp,并捕获文本到名称为name的组里

“(?:exp)”

匹配exp,不捕获匹配的文本,也不给此分组分配组号

以下为零宽断言

“(?=exp)”

匹配exp前面的位置
如 “How are you doing” 正则”(?.+(?=ing))” 这里取ing前所有的字符,并定义了一个捕获分组名字为 “txt” 而”txt”这个组里的值为”How are you do”;

“(?<=exp)”

匹配exp后面的位置
如 “How are you doing” 正则”(?(?<=How).+)” 这里取”How”之后所有的字符,并定义了一个捕获分组名字为 “txt” 而”txt”这个组里的值为” are you doing;。

“(?!exp)”

匹配后面跟的不是exp的位置
如 “123abc” 正则 “\d{3}(?!\d)”匹配3位数字后非数字的结果。

“(?<!exp)”

匹配前面不是exp的位置
如 “abc123 “ 正则 “(?<![0-9])123” 匹配”123”前面是非数字的结果也可写成”(?!<\d)123”。

参考资料

权威指南
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions

正则基础教程
https://github.com/ziishaned/learn-regex/blob/master/translations/README-cn.md
https://www.cnblogs.com/zery/p/3438845.html

正则表达式中?=和?:和?!的理解
https://blog.csdn.net/csm0912/article/details/81206848

VSCode正则使用
https://docs.microsoft.com/en-us/visualstudio/ide/using-regular-expressions-in-visual-studio?view=vs-2019#capture-groups-and-replacement-patterns

正则官方教程
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#Using_simple_patterns

验证工具
https://regexr.com/
https://rubular.com/