跳转到内容

正则表达式

介绍

正则表达式Regular Expression是一种文本模式,包括普通字符(例如:az 之间的字母)和特殊字符(称为"元字符"),可以用来描述和匹配字符串的特定模式。

正则表达式是一种用于模式匹配和搜索文本的工具。

正则表达式提供了一种灵活且强大的方式来查找、替换、验证和提取文本数据。

正则表达式可以应用于各种编程语言和文本处理工具中,如 JavaScriptPythonJavaPerl 等。

模式

正则表达式的模式可以包括以下内容:

  • 字面值字符:例如字母、数字、空格等,可以直接匹配它们自身。
  • 特殊字符:例如点号 .、星号 *、加号 +、问号 ? 等,它们具有特殊的含义和功能。
  • 字符类:用方括号 [ ] 包围的字符集合,用于匹配方括号内的任意一个字符。
  • 元字符:例如 \d\w\s 等,用于匹配特定类型的字符,如数字、字母、空白字符等。
  • 量词:例如 {n}{n,}{n,m} 等,用于指定匹配的次数或范围。
  • 边界符号:例如 ^$\b\B 等,用于匹配字符串的开头、结尾或单词边界位置。

元字符和特性

字符匹配

  • 普通字符:普通字符按照字面意义进行匹配,例如匹配字母 a 将匹配到文本中的 a 字符。
  • 元字符:元字符具有特殊的含义,例如 \d 匹配任意数字字符,\w 匹配任意字母数字字符,. 匹配任意字符(除了换行符)等。

量词

  • *:匹配前面的模式零次或多次。
  • +:匹配前面的模式一次或多次。
  • ?:匹配前面的模式零次或一次。
  • {n}:匹配前面的模式恰好 n 次。
  • {n,}:匹配前面的模式至少 n 次。
  • {n,m}:匹配前面的模式至少 n 次且不超过 m 次。

字符类

  • [ ]:匹配括号内的任意一个字符。例如:[abc] 匹配字符 "a"、"b" 或 "c"。
  • [^ ]:匹配除了括号内的字符以外的任意一个字符。例如:[^abc] 匹配除了字符 "a"、"b" 或 "c" 以外的任意字符。

边界匹配

  • ^:匹配字符串的开头。
  • $:匹配字符串的结尾。
  • \b:匹配单词边界。
  • \B:匹配非单词边界。

分组和捕获

  • ( ):用于分组和捕获子表达式。
  • (?: ):用于分组但不捕获子表达式。

特殊字符

  • \:转义字符,用于匹配特殊字符本身。
  • .:匹配任意字符(除了换行符)。
  • |:用于指定多个模式的选择。

语法

普通字符

字符描述实例
[ABC]匹配 [...] 中的所有字符。[aei] 匹配字符串 google runoob taobao 中所有的 e a 字母。
[^ABC]匹配除了 [...] 中字符的所有字符
[A-Z][A-Z] 表示一个区间,匹配所有大写字母。
[a-z]表示所有小写字母。
.匹配除换行符(\n\r)之外的任何单个字符,相等于 [^\n\r]
[\s\S]匹配所有。\s 是匹配所有空白符,包括换行,\S 非空白符,不包括换行。
\w匹配字母、数字、下划线。等价于 [A-Za-z0-9_]
\d匹配任意一个阿拉伯数字(09)。等价于 [0-9]

非打印字符

非打印字符也可以是正则表达式的组成部分。下表列出了表示非打印字符的转义序列:

字符描述
\cx匹配由 x 指明的控制字符。例如: \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Za-z 之一。否则,将 c 视为一个原义的 'c' 字符。
\f匹配一个换页符。等价于 \x0c\cL
\n匹配一个换行符。等价于 \x0a\cJ
\r匹配一个回车符。等价于 \x0d\cM
\s匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。注意 Unicode 正则表达式会匹配全角空格符。
\S匹配任何非空白字符。等价于 [^ \f\n\r\t\v]
\t匹配一个制表符。等价于 \x09\cI
\v匹配一个垂直制表符。等价于 \x0b\cK

特殊字符

所谓特殊字符,就是一些有特殊含义的字符,如上面说的 runoo\*b 中的 *,简单的说就是表示任何字符串的意思。如果要查找字符串中的 * 符号,则需要对 * 进行转义,即在其前加一个 \*runo\*ob 匹配字符串 runo\*ob

许多元字符要求在试图匹配它们时特别对待。若要匹配这些特殊字符,必须首先使字符“转义”,即,将反斜杠字符\*放在它们前面。下表列出了正则表达式中的特殊字符:

特别字符描述
$匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 \n\r。要匹配 $ 字符本身,请使用 \$
( )标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 \(\)
*匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 \*
+匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 \+
.匹配除换行符 \n 之外的任何单字符。要匹配 .,请使用 \.
[标记一个中括号表达式的开始。要匹配 [,请使用 \[
?匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 \?
\将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如:n 匹配字符 n\n 匹配换行符。序列 \\ 匹配 \,而 \( 则匹配 (
^匹配输入字符串的开始位置,除非在方括号表达式中使用。当该符号在方括号表达式中使用时,表示不接受该方括号表达式中的字符集合。要匹配 ^ 字符本身,请使用 \^
{标记限定符表达式的开始。要匹配 {,请使用 \{
|指明两项之间的一个选择。要匹配 |,请使用 \|

限定符

限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有 *+?{n}{n,}{n,m}6 种。

正则表达式的限定符有:

字符描述
*匹配前面的子表达式零次或多次。例如:zo* 能匹配 z 以及 zoo* 等价于 {0,}
+匹配前面的子表达式一次或多次。例如:zo+ 能匹配 zo 以及 zoo,但不能匹配 z+ 等价于 {1,}
?匹配前面的子表达式零次或一次。例如:do(es)? 可以匹配 dodoesdoxy 中的 dodoes? 等价于 {0,1}
{n}n 是一个非负整数。匹配确定的 n 次。例如:o{2} 不能匹配 Bob 中的 o,但是能匹配 food 中的两个 o
{n,}n 是一个非负整数。至少匹配 n 次。例如:o{2,} 不能匹配 Bob 中的 o,但能匹配 foooood 中的所有 oo{1,} 等价于 o+o{0,} 则等价于 o*
{n,m}mn 均为非负整数,其中 n <= m。最少匹配 n 次且最多匹配 m 次。例如:o{1,3} 将匹配 fooooood 中的前三个 oo{0,1} 等价于 o?。请注意在逗号和两个数之间不能有空格。

以下正则表达式匹配一个正整数,[1-9] 设置第一个数字不是 0[0-9]* 表示任意多个数字:

/[1-9][0-9]*/

*+ 限定符都是贪婪的,因为它们会尽可能多的匹配文字,只有在它们的后面加上一个 ? 就可以实现非贪婪或最小匹配。

例如:您可能搜索 HTML 文档,以查找在 h1 标签内的内容。HTML 代码如下:

<h1>RUNOOB-菜鸟教程</h1>

贪婪:下面的表达式匹配从开始小于符号 (<) 到关闭 h1 标记的大于符号 (>) 之间的所有内容。

/<.*>/

非贪婪:如果您只需要匹配开始和结束 h1 标签,下面的非贪婪表达式只匹配 <h1>

/<.*?>/

定位符

定位符使您能够将正则表达式固定到行首或行尾。它们还使您能够创建这样的正则表达式,这些正则表达式出现在一个单词内、在一个单词的开头或者一个单词的结尾。

定位符用来描述字符串或单词的边界,^$ 分别指字符串的开始与结束,\b 描述单词的前或后边界,\B 表示非单词边界。

正则表达式的定位符有:

字符描述
^匹配输入字符串开始的位置。如果设置了 RegExp 对象的 Multiline 属性,^ 还会与 \n\r 之后的位置匹配。
$匹配输入字符串结尾的位置。如果设置了 RegExp 对象的 Multiline 属性,$ 还会与 \n\r 之前的位置匹配。
\b匹配一个单词边界,即字与空格间的位置。
\B非单词边界匹配。

WARNING

  • 不能将限定符与定位符一起使用。由于在紧靠换行或者单词边界的前面或后面不能有一个以上位置,因此不允许诸如 ^* 之类的表达式。

  • 若要匹配一行文本开始处的文本,请在正则表达式的开始使用 ^ 字符。不要将 ^ 的这种用法与中括号表达式内的用法混淆。

  • 若要匹配一行文本的结束处的文本,请在正则表达式的结束处使用 $ 字符。

  • 若要在搜索章节标题时使用定位点,下面的正则表达式匹配一个章节标题,该标题只包含两个尾随数字,并且出现在行首。

选择

用圆括号 () 将所有选择项括起来,相邻的选择项之间用 | 分隔。

() 表示捕获分组,() 会把每个分组里的匹配的值保存起来, 多个匹配值可以通过数字 n 来查看(n 是一个数字,表示第 n 个捕获组的内容)。

修饰符(标记)

标记也称为修饰符,正则表达式的标记用于指定额外的匹配策略。

标记不写在正则表达式里,标记位于表达式之外,格式如下:

/pattern/flags

下表列出了正则表达式常用的修饰符:

修饰符含义描述
iignore - 不区分大小写将匹配设置为不区分大小写,搜索时不区分大小写: Aa 没有区别。
gglobal - 全局匹配查找所有的匹配项。
mmulti line - 多行匹配使边界字符 ^$ 匹配每一行的开头和结尾,记住是多行,而不是整个字符串的开头和结尾。
s特殊字符圆点 . 中包含换行符 \n默认情况下的圆点 . 是匹配除换行符 \n 之外的任何字符,加上 s 修饰符之后,. 中包含换行符 \n

元字符

字符描述
\将下一个字符标记为一个特殊字符、或一个原义字符、或一个 向后引用、或一个八进制转义符。例如:n 匹配字符 n\n 匹配一个换行符。序列 \\ 匹配 \\( 则匹配 (
^匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 \n\r 之后的位置。
$匹配输入字符串的结束位置。如果设置了 RegExp 对象的 Multiline 属性,$ 也匹配 \n\r 之前的位置。
*匹配前面的子表达式零次或多次。例如:zo* 能匹配 z 以及 zoo* 等价于 {0,}
+匹配前面的子表达式一次或多次。例如:zo+ 能匹配 zo 以及 zoo,但不能匹配 z+ 等价于 {1,}
?匹配前面的子表达式零次或一次。例如:do(es)? 可以匹配 dodoes? 等价于 {0,1}
{n}n 是一个非负整数。匹配确定的 n 次。例如:o{2} 不能匹配 Bob 中的 o,但是能匹配 food 中的两个 o
{n,}n 是一个非负整数。至少匹配 n 次。例如:o{2,} 不能匹配 Bob 中的 o,但能匹配 foooood 中的所有 oo{1,} 等价于 o+o{0,} 则等价于 o*
{n,m}mn 均为非负整数,其中 n <= m。最少匹配 n 次且最多匹配 m 次。例如:o{1,3} 将匹配 fooooood 中的前三个 oo{0,1} 等价于 o?。请注意在逗号和两个数之间不能有空格。
?当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如:对于字符串 ooooo+? 将匹配单个 o,而 o+ 将匹配所有 o
.匹配除换行符(\n\r)之外的任何单个字符。
(pattern)匹配 pattern 并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到,在 VBScript 中使用 SubMatches 集合,在 JScript 中则使用 $0…$9 属性。要匹配圆括号字符,请使用 \(\)
(?:pattern)匹配 pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用 "或" 字符来组合一个模式的各个部分是很有用。
(?=pattern)正向肯定预查(look ahead positive assert),在任何匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如:Windows(?=2000) 能匹配 Windows2000 中的 Windows,但不能匹配 Windows3.1 中的 Windows。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
(?!pattern)正向否定预查(negative assert),在任何不匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如 Windows(?!2000) 能匹配 Windows3.1 中的 Windows,但不能匹配 Windows2000 中的 Windows。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
(?<=pattern)反向(look behind)肯定预查,与正向肯定预查类似,只是方向相反。例如:"(?<=2000)Windows"能匹配"2000Windows"中的"Windows",但不能匹配"3.1Windows"中的"Windows"。
(?<!pattern)反向否定预查,与正向否定预查类似,只是方向相反。例如"(?<!2000)Windows"能匹配"3.1Windows"中的"Windows",但不能匹配"2000Windows"中的"Windows"。
[xyz]字符集合。匹配所包含的任意一个字符。例如: [abc] 可以匹配 plain 中的 a
[^xyz]负值字符集合。匹配未包含的任意字符。例如: [^abc] 可以匹配 plain 中的 plin
[a-z]字符范围。匹配指定范围内的任意字符。例如:[a-z] 可以匹配 az 范围内的任意小写字母字符。
[^a-z]负值字符范围。匹配任何不在指定范围内的任意字符。例如:[^a-z] 可以匹配任何不在 az 范围内的任意字符。
\b匹配一个单词边界,也就是指单词和空格间的位置。例如: er\b 可以匹配 never 中的 er,但不能匹配 verb 中的 er
\B匹配非单词边界。er\B 能匹配 verb 中的 er,但不能匹配 never 中的 er
\cx匹配由 x 指明的控制字符。例如: \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Za-z 之一。否则,将 c 视为一个原义的 c 字符。
\d匹配一个数字字符。等价于 [0-9]
\D匹配一个非数字字符。等价于 [^0-9]
\f匹配一个换页符。等价于 \x0c\cL
\n匹配一个换行符。等价于 \x0a\cJ
\r匹配一个回车符。等价于 \x0d\cM
\s匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]
\S匹配任何非空白字符。等价于 [^ \f\n\r\t\v]
\t匹配一个制表符。等价于 \x09\cI
\v匹配一个垂直制表符。等价于 \x0b\cK
\w匹配字母、数字、下划线。等价于 [A-Za-z0-9_]
\W匹配非字母、数字、下划线。等价于 [^A-Za-z0-9_]
\xn匹配 n,其中 n 为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如:\x41 匹配 A\x041 则等价于 \x04 & 1。正则表达式中可以使用 ASCII 编码。
\num匹配 num,其中 num 是一个正整数。对所获取的匹配的引用。例如:(.)\1 匹配两个连续的相同字符。
\n标识一个八进制转义值或一个向后引用。如果 \n 之前至少 n 个获取的子表达式,则 n 为向后引用。否则,如果 n 为八进制数字 (0-7),则 n 为一个八进制转义值。
\nm标识一个八进制转义值或一个向后引用。如果 \nm 之前至少有 nm 个获得子表达式,则 nm 为向后引用。如果 \nm 之前至少有 n 个获取,则 n 为一个后跟文字 m 的向后引用。如果前面的条件都不满足,若 nm 均为八进制数字 (0-7),则 \nm 将匹配八进制转义值 nm
\nml如果 n 为八进制数字 (0-3),且 ml 均为八进制数字 (0-7),则匹配八进制转义值 nml
\un匹配 n,其中 n 是一个用四个十六进制数字表示的 Unicode 字符。

优先级

以下是一些常见正则表达式运算符按照优先级从高到低的顺序:

  • 转义符号: \ 是用于转义其他特殊字符的转义符号。它具有最高的优先级。

    示例:\d\. 等,其中 \d 匹配数字,\. 匹配点号。

  • 括号: 圆括号 () 用于创建子表达式,具有高于其他运算符的优先级。

    示例:(abc)+ 匹配 abc 一次或多次。

  • 量词: 量词指定前面的元素可以重复的次数。

    示例:a* 匹配零个或多个 a

  • 字符类: 字符类使用方括号 [] 表示,用于匹配括号内的任意字符。

    示例:[aeiou] 匹配任何一个元音字母。

  • 断言: 断言是用于检查字符串中特定位置的条件的元素。

    示例:^ 表示行的开头,$ 表示行的结尾。

  • 连接: 连接在没有其他运算符的情况下表示字符之间的简单连接。

    示例:abc 匹配 abc

  • 管道: 管道符号 | 表示“或”关系,用于在多个模式之间选择一个。

    示例:cat|dog 匹配 catdog