【Regular Expression】正则表达式(Regular Expression)

Posted by 西维蜀黍 on 2019-07-10, Last Modified on 2022-12-10

非打印字符

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

字符 描述
\cx 匹配由x指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 ‘c’ 字符。
\f 匹配一个换页符。等价于 \x0c 和 \cL。
\n 匹配一个换行符。等价于 \x0a 和 \cJ。
\r 匹配一个回车符。等价于 \x0d 和 \cM。
\s 匹配任何空白字符,包括空格(space)、制表符(tab)、换页符(newline)等等。等价于 [\f\n\r\t\v]。注意 Unicode 正则表达式会匹配全角空格符。

\S 匹配任何非空白字符,即除空格(space)、制表符(tab)、换页符(newline)之外的任何字符。等价于 [^\f\n\r\t\v]

\t 匹配一个制表符。等价于 \x09 和 \cI。
\v 匹配一个垂直制表符。等价于 \x0b 和 \cK。
\0 Matches a null character, most often visually represented in unicode using U+2400.

特殊字符

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

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

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

限定符(Quantifier)

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

正则表达式的限定符有:

字符 描述
* 匹配前面的子表达式零次或多次。例如,zo* 能匹配 “z” 以及 “zoo”。* 等价于 {0,}
+ 匹配前面的子表达式一次或多次。例如,zo+ 能匹配 “zo” 以及 “zoo”,但不能匹配 “z”。+ 等价于 {1,}
? 匹配前面的子表达式零次或一次。例如,do(es)? 可以匹配 “do” 、 “does” 中的 “does” 、 “doxy” 中的 “do” 。? 等价于 {0,1}
{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?。请注意在逗号和两个数之间不能有空格。

Meta Sequences

字符 描述
. Matches any character other than newline (or including newline with the /s flag)

\d Matches any decimal digit. Equivalent to [0-9].

\D Matches anything other than a decimal digit.

\w Matches any letter, digit or underscore. Equivalent to [a-zA-Z0-9_].

\W Matches anything other than a letter, digit or underscore.

Flags/Modifiers

字符 描述
g Tells the engine not to stop after the first match has been found, but rather to continue until no more matches can be found.

m Multiline, the ^ and $ anchors now match at the beginning/end of each line respectively, instead of beginning/end of the entire string.

一些实例

Case 1 - 匹配单个字符

例子 1 - 匹配单个指定字符

Pattern:

/3/

表示匹配任何为“3”的字符。

比如,input为:

123
3345

匹配到了三次。

例子 1 - 匹配单个的任意字符

Pattern:

/.+/

表示匹配长度尽可能长的一个字符串。

比如,input为:

line1
 line2

匹配到了两次。

Case 2 - [Character Set] 匹配在给定字符集合中的字符 - [<character_candidate>...]

匹配一个字符

  • [abc]:匹配一个字符,且这个字符必须是 a,b 或 c
  • [^abc]:匹配除了 a,b 和 c 之外的一个字符
  • [a-z]:匹配在 a - z 范围内的一个字符
  • [^a-z]:匹配在 a - z 范围一个字符
  • [a-zA-Z]:匹配在 a - z 或 A - Z范围内的一个字符
  • [\u4e00-\u9fa5]:匹配一个中文字符。
  • .:匹配任何一个字符
  • \s:匹配任何一个空白字符
  • \S:匹配任何一个非空白字符
  • \d:匹配任何一个数字字符
  • \D:匹配任何一个非数字字符
  • \w:匹配任何一个字(word)字符
  • \W:匹配任何一个非字(word)字符

匹配一个字符串(包含1个或多个字符)

  • [0-9]+:匹配包含一个或多个数字的一个字符串( [0-9] 匹配单个数字,+ 匹配一个或者多个)

注意,如果要匹配 ^ 字符本身,请使用 \^

例子 1 - 匹配范围内的一个数字

Pattern:

/[0-9]/

表示匹配任何为数字(0,1,…9)的一个字符

比如,input为:

匹配到了五次。

例子 2 - 匹配范围内的一个小写字母

类似地,

Pattern:

/[a-z]/

表示匹配任何为小写字母(a,b,…z)的一个字符

比如,input为:

匹配到了四次。

例子 3 - 匹配一个中文字符

Pattern:

/[\u4e00-\u9fa5]/

表示匹配任何一个中文字符。

比如,input为:

Anything but 中文啊

匹配到了三次。

例子 4 - 匹配范围内的一个小写或大写字母

Pattern:

/[a-zA-Z]/

表示匹配任何为小写或大写字母(a,A,b,B…z,Z)的一个字符

比如,input为:

abc123DEF

匹配到了六次。

例子 5 - 匹配一个非小写字母字符

Pattern:

/[^a-z]/

表示匹配任何为非小写字母(a,b,…z)的一个字符

比如,input为:

Anything but a-z.

匹配到了五次。

例子 6 - 匹配多个连续的小写字母字符串

Pattern:

/[^a-z]+/

表示匹配任何每个字符均为小写字母(a,b,…z)的一个字符串

比如,input为:

Anything  but  a -z....

匹配到了五次。

Case 3 - [Quantifier] 指定匹配字符串的匹配长度 - {<minimum_match_times>,[<maximum_match_times>]}

其实我们提到了,限定符(Quantifier)用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有 ***** 或 +?{n}{n,}{n,m} 共6种。

正则表达式的限定符有:

字符 描述
* 匹配前面的子表达式零次或多次(尽可能少的匹配,懒惰策略)。例如,zo* 能匹配 “z” 以及 “zoo”。* 等价于 {0,}
+ 匹配前面的子表达式一次或多次(尽可能多的匹配,贪心策略)。例如,zo+ 能匹配 “zo” 以及 “zoo”,但不能匹配 “z”。+ 等价于 {1,}
? 匹配前面的子表达式零次或一次(尽可能多的匹配,贪心策略)。例如,do(es)? 可以匹配 “do” 、 “does” 中的 “does” 、 “doxy” 中的 “do” 。? 等价于 {0,1}
{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?。请注意在逗号和两个数之间不能有空格。

例子 1 - 匹配0个或一个 a - ?(贪心策略)

Pattern:

/a?/

表示匹配的包含0个或1个 a 的一个字符

比如,input为:

abca

匹配到了五次,其中匹配到了包含0个字符长度的字符三次。

例子 2 - 匹配0个或多个 a - *(懒惰策略)

Pattern:

/ba*/

表示匹配包含一个 b, 紧接着包含0个或多个 a 的一个字符串

比如,input为:

a ba baa aaa ba b

匹配到了四次,可以发现,由于 * 是采用贪心匹配的原则(即当匹配到了一个 b 之后,尽量少的匹配到 a ),所以永远不会匹配到 ba(因为当匹配到 b 之后,已经满足匹配 pattern了)。

例子 3 - 匹配1个或多个 a - +(贪心策略)

Pattern:

/ba*/

表示匹配包含一个 b, 紧接着包含0个或多个 a 的一个字符串

比如,input为:

a ba baa aaa ba b

匹配到了三次。

例子 4 - 匹配3个连续的 a - {<match_times>}

Pattern:

/a{3}/

比如,input为:

a aa aaa aaaa

匹配到了四次。

例子 5 - 匹配包含3个以上连续的 a 的字符串 - {<min_match_times>,}

Pattern:

/a{3,}/

比如,input为:

a aa aaa aaaa aaaaaa

匹配到了三次。

Case 4 - 匹配开头或结尾字符

例子 1 - 匹配开头的第一个单词

Pattern:

/^\w+/

注意,\w 的含义是匹配任何英文字母、数字或者下划线(underscore),等价于 [a-zA-Z0-9_]

比如,input为:

start of string

匹配到了一次。

例子 2 - 匹配结尾的最后一个单词

Pattern:

/\w+$/

比如,input为:

end of string

匹配到了一次。

Case 5 - 混合使用

Reference