正则表达式
基本匹配
如有一个字符串abc123dfsfsd, 正则表达式abc123。
匹配结果:abc123
任意匹配
., 匹配任意的字符
如有字符串abc123, 正则表达式.
匹配结果:a,b,c,1,2,3
特殊匹配
\w, 匹配字母、数字和下划线。\W, 匹配除字母、数字和下划线之外的字符。\d, 仅匹配数字。\D, 匹配除数字之外的字符。\s, 匹配空白符。\S, 匹配空白符之外的字符。
字符集
[ ],中括号内的字符组成一个字符集,匹配集合内的任意字符。
如有字符串beer deer feer, 正则表达式[bdf]eer.
匹配结果:beer,deer,feer
否定字符集
^在字符集的首部, 代表不匹配字符集中任意字符。
如有字符串beer deer feer, 正则表达式[^bd]eer.
匹配结果:feer
字符范围
a-z, 代表匹配字符a到z左闭右闭的字符范围,数字同理。
字符次数
+,代表前一个字符出现一次或者多次。
如有字符串br ber beer, 正则表达式be+r。
匹配结果:ber,beer*, 代表前一个字符出现0次或者多次。
如有字符串br ber beer, 正则表达式be*r。
匹配结果:br,ber,beer?, 代表前一个字符出现0次或者一次(可选的)。
如有字符串br ber beer, 正则表达式be?r。
匹配结果:br,ber{n},代表前一个字符出现n次。
如有字符串br ber beer, 正则表达式be{2}r。
匹配结果:beer{n,m},代表前一个字符出现n-m次; m为空白,也就是{n,},代表前一个字符出现n-∞次 。
如有字符串br ber beer, 正则表达式be{1,2}r。
匹配结果:ber,beer
表达式分组
( ), 将正则表达式包裹在( )内,代表一组正则表达式。
引用组
定义号表达式分组后,可以用\n,代表引用第n组的表达式。
如有字符串ha-ha,haa-haa, 正则表达式(ha)-\1,(haa)-\2.
上述表达式等价于(ha)-(ha),(haa)-(haa)
匹配结果:ha-ha,haa-haa
非捕获组
(?:), 表示对表达式分组,但不会被引用捕获;匹配 pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。
如有字符串ha-ha,haa-haa, 正则表达式(?:ha)-ha,(haa)-\1.
上述表达式等价于(ha)-ha,(haa)-(haa)
匹配结果:ha-ha,haa-haa
零宽断言也是非捕获组
表达式分支
|, 它左侧为一个分支,右侧为另一个分支。
如有字符串cat rat dog, 正则表达式(c|r)at|dog.
匹配结果:cat,rat,dog
转义字符
在书写正则表达式时,我们会用到 { } [ ] / \ + * . $^ | ? 这些特殊字符 。为了匹配这些特殊字符本身,我们需要通过 \ 将它们转义。例如,要匹配文本中的. 和 *,我们需要在它们前面添加一个 \.
如有字符串(*)Asterisk ., 正则表达式(\*|\.).
匹配结果:*,.
字符串行间限定
匹配字符串的开始
^, 它放在表达式前面,代表匹配字符串的开始。
若有字符串:
1 | Basic Omellette Recipe |
正则表达式(^[0-9]).*
匹配结果:
1 | 1. 4 eggs, beaten |
匹配字符串的结尾
$, 它加在表达式后面,代表匹配字符串的结尾。
若有字符串:
1 | https://domain.com/what-is-html.html |
正则表达式.*(html$)
匹配结果:
1 | https://domain.com/what-is-html.html |
零宽断言
如果我们希望正在写的词语出现在另一个词语之前或之后,我们需要使用「零宽断言」。
正向先行断言: (?=)
(?=字符串), 我们要匹配文本中的小时值。为了只匹配后面有 PM 的数值,我们需要在表达式后面使用正向先行断言(?=),并在括号内的 = 后面添加 PM。
若有字符串Date: 4 Aug 3PM
正则表达式\d+(?=PM)
匹配结果:3
负向先行断言: (?!)
(?!字符串), 我们要在文本中匹配除小时值以外的数字。我们需要在表达式后面使用负向先行断言 (?!),并在括号内的 !后面添加 PM,从而只匹配没有PM的数值。
若有字符串Date: 4 Aug 3PM
正则表达式\d+(?!PM)
匹配结果:4
正向后行断言: (?<=)
(?<=),我们要匹配文本中的金额数。为了只匹配前面带有 $ 的数字。我们要在表达式前面使用正向后行断言(?<=),并在括号内的 = 后面添加 \$。
若有字符串Product Code: 1064 Price: $5
正则表达式(?<=\$)\d+
匹配结果:5
负向后行断言: (?<!)
(?<!), 我们要在文本中匹配除价格外的数字。为了只匹配前面没有 $ 的数字,我们要在表达式前用负向后行断言 (?<!),并在括号内的 ! 后面添加 \$。
若有字符串Product Code: 1064 Price: $5
正则表达式(?<!\$)\d+
匹配结果:1064
标志(修饰符)
标志改变表达式的输出。这就是标志也称为 修饰符 的原因。标志决定表达式是否将文本视作单独的行处理,是否区分大小写,或者是否查找所有匹配项。
全局标志: global
全局标志使表达式选中所有匹配项,如果不启用全局标志,那么表达式只会匹配第一个匹配项。现在,请启用全局标志,以便匹配所有匹配项。
多行标志: multiline
正则表达式将所有文本视作一行。但如果我们使用了多行标志,它就会单独处理每一行。这次,我们将根据每一行行末的规律来写出表达式,现在,请启用多行标志来查找所有匹配项。
忽略大小写标志: insensitive
为了使我们编写的表达式不再大小写敏感,我们必须启用 不区分大小写 标志
贪婪匹配
正则表达式默认执行贪婪匹配。这意味着匹配内容会尽可能长。请看下面的示例,它匹配任何以 r 结尾的字符串,以及前面带有该字符串的文本,但它不会在第一个 r 处停止匹配。
字符串ber beer beeer beeeer
正则表达式.*r
匹配结果:ber beer beeer beeeer
懒惰匹配
与贪婪匹配不同,懒惰匹配在第一次匹配时停止。下面的例子中,在 * 之后添加 ?,将查找以 r 结尾且前面带有任意字符的第一个匹配项。这意味着本次匹配将会在第一个字母 r 处停止。
字符串ber beer beeer beeeer
正则表达式.*?r
匹配结果:ber