正则表达式(Regular Expression)是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为”元字符”)。

语法

普通字符

  • [ABC] : 匹配[…]中的所有字符
  • [^ABC]::匹配除了A,B,C的所有字符
  • [A-Z]:表示一个区间,匹配所有大写字母
  • . : 匹配除换行符(\n、\r)之外的任何单个字符,相等于 [^\n\r]
  • \w: 匹配字母、数字、下划线。等价于 [A-Za-z0-9_]
  • [\s\S]: 匹配所有。\s 是匹配所有空白符,包括换行,\S 非空白符,不包括换行

image.png

非打印字符

  • \cx: 匹配由x指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 ‘c’ 字符。
  • \f: 匹配一个换页符。等价于 \x0c 和 \cL。
  • \n: 匹配一个换行符。等价于 \x0a 和 \cJ。
  • \r: 匹配一个回车符。等价于 \x0d 和 \cM。
  • \s:匹配任何空白字符。等价于[\f\n\r\t\v]
  • \S:匹配任何非空白字符
  • \t: 匹配一个制表符。等价于 \x09 和 \cI。
  • \v: 匹配一个垂直制表符。等价于 \x0b 和 \cK。

特殊字符

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

限定符

  • : 匹配前面的子表达式零次或多次。例如,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-9]设置第一个数字不是 0,[0-9]* 表示任意多个数字

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

  • 设置 0~99 的两位数,可以使用下面的表达式来至少指定一位但至多两位数字。

/[0-9]{1,2}/

  • 上面的表达式的缺点是,只能匹配两位数字,而且可以匹配 0、00、01、10 99 的章节编号仍只匹配开头两位数字。改进下,匹配 1~99 的正整数表达式如下:

/[1-9][0-9]?//[1-9][0-9]{0,1}/
通过在 *、+ 或 ? 限定符之后放置 ?,该表达式从”贪婪”表达式转换为”非贪婪”表达式或者最小匹配。

定位符

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

选择

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

以下列出 ?=、?<=、?!、?<! 的使用区别

  • exp1(?=exp2):查找 exp2 前面的 exp1。
  • (?<=exp2)exp1:查找 exp2 后面的 exp1。
  • exp1(?!exp2):查找后面不是 exp2 的 exp1。
  • (?<!exp2)exp1:查找前面不是 exp2 的 exp1。

反向引用

可以使用非捕获元字符 ?:、?= 或 ?! 来重写捕获,忽略对相关匹配的保存。
正则表达式后面的全局标记 g 指定将该表达式应用到输入字符串中能够查找到的尽可能多的匹配。
表达式的结尾处的不区分大小写 i 标记指定不区分大小写。

修饰符

  • i: ignore - 不区分大小写
  • g: global - 全局匹配
  • m: multi line - 多行匹配 使边界字符 ^ 和 $ 匹配每一行的开头和结尾,记住是多行,而不是整个字符串的开头和结尾。
  • s: 特殊字符圆点 . 中包含换行符 \n 默认情况下的圆点 . 是 匹配除换行符 \n 之外的任何字符,加上 s 修饰符之后, . 中包含换行符 \n。

元字符

  • x|y : 匹配 x 或 y。例如,’z|food’ 能匹配 “z” 或 “food”。’(z|f)ood’ 则匹配 “zood” 或 “food”。
  • [^xyz] : 负值字符集合。匹配未包含的任意字符。例如, ‘[^abc]’ 可以匹配 “plain” 中的’p’、’l’、’i’、’n’。
  • \d: 匹配一个数字字符。等价于 [0-9]。
  • \D: 匹配一个非数字字符。等价于 [^0-9]。
  • \num: 匹配 num,其中 num 是一个正整数。对所获取的匹配的引用。例如,’(.)\1’ 匹配两个连续的相同字符。
  • (pattern): 匹配 pattern 并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到,在VBScript 中使用 SubMatches 集合,在JScript 中则使用 $0…$9 属性。要匹配圆括号字符,请使用 ‘(‘ 或 ‘)‘。
  • (?:pattern): 匹配 pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用 “或” 字符 (|) 来组合一个模式的各个部分是很有用。例如, ‘industr(?:y|ies) 就是一个比 ‘industry|industries’ 更简略的表达式。
  • (?=pattern): 正向肯定预查(look ahead positive assert),在任何匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,”Windows(?=95|98|NT|2000)”能匹配”Windows2000”中的”Windows”,但不能匹配”Windows3.1”中的”Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
  • (?!pattern): 正向否定预查(negative assert),在任何不匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如”Windows(?!95|98|NT|2000)”能匹配”Windows3.1”中的”Windows”,但不能匹配”Windows2000”中的”Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
  • (?<=pattern): 反向(look behind)肯定预查,与正向肯定预查类似,只是方向相反。例如,”(?<=95|98|NT|2000)Windows”能匹配”2000Windows”中的”Windows”,但不能匹配”3.1Windows”中的”Windows”。
  • (?<!pattern): 反向否定预查,与正向否定预查类似,只是方向相反。例如”(?<!95|98|NT|2000)Windows”能匹配”3.1Windows”中的”Windows”,但不能匹配”2000Windows”中的”Windows”。
    ```go var str = “dadiao 2333”; str.match(/dadiao (?:2222|2333|1211)/) //[‘dadiao 2333’]; str.match(/dadiao (?=2222|2333|1211/) // [‘dadiao ‘];

str.match(/dadiao (?!=2222)/) //[‘dadiao ‘]

str.match(/dadiao (2222|2333|1211)/) //[‘dadiao 2333’, ‘2333’]; `` 匹配邮箱<br />/\b[\w]+@[\w]+.[\w]+\b/`

示例

简单表达式

/a/``/7/``/M
/a7M 组合了单字符表达式:a、7 和 M。

字符匹配

/a.z 匹配 aac、abc、acc、adc 等等,以及 a1c、a2c、a-c 和 a#c

中括号表达式

若要创建匹配字符组的一个列表,请在方括号([ 和 ])内放置一个或更多单个字符。当字符括在中括号内时,该列表称为”中括号表达式”。
/Chapter [12345]/ /Chapter [1-5]/括在中括号表达式中的字符只匹配处于正则表达式中该位置的单个字符。以下正则表达式匹配 Chapter 1、Chapter 2、Chapter 3、Chapter 4 和 Chapter 5
[\-] 若要在中括号表达式中包括连字符
[-a-z]``[a-z-]匹配所有小写字母和连字符
/Chapter [^12345]/ 匹配1、2、3、4 或 5 之外的任何数字和字符
/[A-Za-z0-9]/ 中括号表达式的典型用途是指定任何大写或小写字母或任何数字的匹配

替换和分组

/^(Chapter|Section) [1-9][0-9]{0,1}$/ 匹配出现在行首和行尾、后面跟一个或两个数字的 Chapter 或 Section

其他示例

一个单词连续出现的位置 /\b([a-zA-Z]+)\1\b/
匹配一个 URL 解析为协议、域、端口及相对路径 /(\w+):\/\/([^/:]+):(\d+)\/([^/:]+)/
定位章节的位置 /^(Chapter|Section) [1-9][0-9]{0,1}$/
a 至 z 共 26个 字母再加一个 - 号 /[-a-z]/
可匹配 chapter,而不能匹配 terminal。 /ter\b/
可匹配 chapter,而不能匹配 aptitude /\Bapt/
可匹配 Windows95 或 Windows98 或 WindowsNT,当找到一个匹配后,从 Windows 后面开始进行下一次的检索匹配 /Windows(?=95|98|NT)/
匹配空行 /^\s*$/
验证由两位数字、一个连字符再加 5 位数字组成的 ID 号 /\d\d-\d{5}/
匹配 HTML 标记 /<[a-zA-Z]+.*?>([\s\S]*?)/
匹配 {hello} /hello/
匹配 {gray, grey} /(gray)|(grey)/``gr(a|e)y``gr[ae]y
匹配 {babble, bebble, bibble, bobble, bubble} /b[aeiou]bble/
匹配 {bat, cat, hat, mat, nat, oat, pat, Pat, ot} /([bchmnopP]a|o)t/
匹配 {color, colour} /colou?r/
匹配 {regex, regexes, regexp, regexps} /regex(ex|es|ps|p)?/
匹配 {ggle, gogle, google, gooogle, goooogle, …} /go*gle/
匹配 {gogle, google, gooogle, goooogle, …} /go+gle/
匹配 {google, googoogle, googoogoogle, googoogoogoogle, …} /g(oog)+le/
匹配 {zzz} /z{3}/
匹配 {zzz, zzzz, zzzzz, zzzzzz} /z{3,6}/
匹配 {zzz, zzzz, zzzzz, …} /z{3,}/
匹配 {Brainfk, brainfk} /[Bb]rainf\*\*k/
匹配 {0,1,2,3,4,5,6,7,8,9} /\d/
匹配 11 个数字,以 1 开头 /1\d{10}/
匹配 2 到 36 范围内的整数 /[2-9]|([12][0-9])|(3[0-6])/
匹配 Hello 后跟换行符,后跟 world /hello\nworld/
包含一个正整数或包含两位小数位的浮点数。 /\d+(.\d{2}){0,1}/
排除 、@ 、# 三个特色符号 `/[^\\@#]/<br /> 匹配 // 开头的注释/\/\/[^\r\n]*[\r\n]/<br /> 匹配以 "dog" 开始/^dog/<br /> 匹配以 "dog" 结尾/dog$/<br /> is exactly "dog"/^dog$/`