RegEx101 正则入门笔记
November 10, 2022
RegEx101 正则入门笔记 #
正则表达式的两种基本用途:搜索和替换。给定一个正则表达式,它要么匹配一些文本(进行一次搜索),要么匹配并替换一些文本(进行一次替换)。
- 非常好的在线正则表达式匹配检测工具: regex101: build, test, and debug regex 学习与工作上都非常好用
匹配单个字符 #
正则表达式,也被称为模式,其实是一些由字符构成的字符串。这些字符可以是字面字符(普通文本)或元字符(有特殊含义的字符)。
普通文本
- 正则表达式是区分大小写的。
任意字符
注意正则表达式使用字符串内容来匹配模式。匹配到的未必总是整个字符串,也可能是与某个模式相匹配的子串。在上面的例子里,我们使用的正则表达式并不能匹配完整的文件名, 而是只匹配了其中一部分。如果你需要把某个正则表达式的匹配结果传递到其他代码或应用程序里做进一步处理,就必须记住这种差异。
特殊字符
.
表示匹配任意单个字符。\
是一个元字符(metacharacter,表示这个字符有特殊含义,代表的不是字符本身)。
.a.\.
结果:na1.xls
第一个.匹配a前面的单个字符;第二个.匹配a后面的单个字符;\.作为转义匹配真正的.符号
匹配一组字符 #
在正则表达式里,我们可以使用元字符 [
和 ]
来定义一个字符集合。在使用 [
和 ]
定义的字符集合里,出现在 [
和 ]
之间的所有字符都是该集合的组成部分,必须匹配其中某个成员(但并非全部)。
- 此处的
[
和]
代表着强制匹配其中的元素。只有存在才能够匹配成功。 [
和]
不匹配任何字符,它们只负责定义一个字符集合。接下来,再由真正的 regex 匹配部分参与匹配操作。- 使用
[
和]
的字符集合在不需要区分字母大小写(或是只需要匹配某个特定部分)的搜索操作里比较常见。 -
利用字符集合区间
-
连字符,一种特殊的元字符。可以用这种连字符来定义字符区间。
一些合法的字符区间:
[a-z]
:匹配 a 到 z 所有小写字母[A-Z]
:匹配 A 到 Z 所有大写字母[A-z]
:匹配从 ASCⅡ字符 A 到 ASCIⅡ字符 z 的所有字母。这个模式一般不常用,因为它还包含[
和^
等在 ASCⅡ字符表里排列在 Z 和 a 之间的字符。
字符区间的首、尾字符可以是 ASCⅡ字符表里的任意字符。但在实际工作中,最常用的字符区间还是数字字符区间和字母字符区间。
注意
-
(连字符)是一个特殊的元字符,它只有出现在[
和]
之间的时候才是元字符。在字符集合以外的地方,-
只是一个普通字符,只能与-
本身相匹配。因此,在正则表达式里,-
字符不需要被转义。
在同一个字符集合里可以给出多个字符区间。比如说,下面这个模式可以匹配任何一个字母(无论大小写)或数字,但除此以外的其他字符(既不是数字也不是字母的字符)都不匹配:
[A-Za-z0-9]==
[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789]
排除
字符集合通常用来指定一组必须匹配其中之一的字符。但在某些场合,我们需要反过来做,即指定一组不需要匹配的字符。换句话说,就是排除字符集合里指定的那些字符。
- 使用元字符
^
来排除某个字符集合。而不用逐个列出要匹配的字符。
[^0-9]这种用法就恰好与[0-9]相反
小结
- 元字符
[
和]
用来定义一个字符集合,其含义是必须匹配该集合里的字符之一(各个字符之间是 OR 的关系,而不是 AND 的关系)。 - 定义一个字符集合的具体做法有两种:
- 一是把所有的字符都列举出来;
- 二是利用元字符
-
以字符区间的方式给出。可以用元字符^
排除字符集合,强制匹配指定字符集合之外的字符。
元字符 #
转义字符
因为元字符在正则表达式里有着特殊的含义,所以这些字符就无法用来代表它们本身。比如说,你不能使用 [
来匹配 [
本身,也不能使用 .
来匹配 .
本身。
- 通过加上通用的转义字符
\
对其进行转义 - 对元字符进行转义需要用到
\
字符。这意味着\
字符也是一个元字符,它的特殊含义是对其他元字符进行转义。在需要匹配\
本身的时候,我们必须把它转义为\\
。
匹配空白字符
- 元字符大致可以分为两种:一种是用来匹配文本的(比如
.
),另一种是正则表达式语法的组成部分(比如[
和]
)。 - 空白字符匹配:
-
匹配特定字符类型
数字元字符
匹配字母数字(与非字母数字)
匹配空白字符
- 因此,正则表达式的写法并不唯一。只需挑选最舒服的即可。
匹配十六进制或八进制数值
- 十六进制:使用前缀
\x
给出 - 八进制:使用前缀
\0
给出
POSIX 字符类
POSX 是一种特殊的标准字符类集,也是许多(但不是所有)正则表达式实现都支持的一种简写形式。
重复匹配 #
目的是要匹配尽可能多的字符。可以通过几种特殊的元字符实现。
匹配一个或多个字符
- 要匹配某个字符或字符集合,只要简单地在其后面加上一个
+
字符就行了。 +
匹配一个或多个字符(至少一个;不匹配零个字符的情况)+
还可以用来匹配一个或多个字符集合。配合之前的[
或]
来实现
注意你可能已经注意到了:我们没有对字符集合
[\w.]
里的.字符进行转义,但依然能够匹配.字符。一般来说,当在字符集合里使用的时候,像.和+这样的元字符将被解释为普通字符,不需要转义,但转义了也没有坏处。[\w\.]
的使用效果与[w\.]
是一样的。
匹配零个或多个字符
- 这种匹配使用
*
元字符来完成。其与+
的用法完全一样,但可以支持匹配零个或多个。 - 注意:可以把
*
理解为一种“使其可选”(make it optional)的元字符。+
需要最少匹配一次,而*
可以匹配多次,也可以一次都不匹配。
匹配零个或一个字符
- 使用元字符
?
来匹配可选文本 ?
只能匹配某个字符或字符集合的零次或一次出现。最多不超过一次。非常适合匹配一段文本中某个特定的可选字符。
匹配的重复次数
为了解决这些指定重复的问题并对重复性匹配有更多的控制权,正则表达式允许使用重复范围(interval)。重复范围在 {
和 }
之间指定。
- 要想设置具体的匹配次数,把数字写在
{}
之间即可。 - 如:
{3}
表示匹配前一个字符或字符集合 3 次。若只匹配两次,则不算匹配成功。
区间范围
{}
语法还可以用来为重复匹配次数设定一个区间范围,也就是匹配的最小次数和最大次数。
- 区间必须以
{2,4}
(最少重复 2 次,最多重复 4 次)这样的形式给出。
匹配至少重复多少次
指定至少要匹配多少次(不指定最大匹配次数) 。这种用法的语法类似于区间范围语法,只是省略了最大值部分而已。
- 比如说,
{3,}
表示至少重复 3 次,换句话说,就是“重复 3 次或更多次” 。 - 此时,
+
在功能上便等价于{1,}
防止过度匹配
?
的匹配范围有限(仅限零次或一次匹配) ,当使用精确数量或区间时,重复范围匹配也是如此。但其他重复匹配形式在重复次数方面都没有上限值,而这样做有时会导致过度匹配的现象。
*
和+
都是所谓的“贪婪型”(greedy)元字符, 其匹配行为是多多益善而不是适可而止。它们会尽可能地从一段文本的开头一直匹配到末尾,而不是碰到第一个匹配时就停止。这是有意设的,量词就是贪婪的。- 在不需要这种“贪婪行为”的时候该怎么办?答案是使用这些量词的“懒惰型”(lazy)版本(之所以称之为“懒惰型”是因为其匹配尽可能少的字符,而非尽可能多地去匹配)。懒惰型量词的写法是在贪婪型量词后面加上一个
?
。
位置匹配 #
单词边界
\b
是由其所指定的单词边界。用来匹配一个单词的开头或结尾。\b
匹配的是字符之间的一个位置,一边是单词另一边是其他内容。- 如果想要匹配完整的单词,就必须在匹配的文本前后都加上
\b
字符串边界
^
匹配一个字符串的开头位置$
匹配字符串结尾位置