正则表达式测试

正则表达式测试工具,是检验正则模式和给定文本之间是否匹配的工具,它能够把匹配到的结果高亮显示,是在线验证正则表达式的必备工具。本工具使用原生 JS 实现,具有极高的正则解析和匹配效率。另外,本工具还提供了各种常用正则表达式的写法,可以作为日常书写正则表达式时的参考。

正则表达式简介

一、发展历史

如果你曾经使用过或听说过正则表达式,就应该知道正则表达式是一种字符匹配的模式,是为检索字符这个基本需求发展起来的。但关于正则表达式更早的历史,则可以追溯至科学家对人类神经系统如何工作的早期研究。

1951 年, 一位名叫 Stephen Kleene 的数学家在 McCulloch 和 Pitts 早期工作的基础上,发表了一篇标题为《神经网事件的表示法》的论文,正式引入了正则表达式的概念。正则表达式就是用来描述他称为「正则集的代数」的表达式,因此采用「正则表达式」这个术语。

随后,Unix 主要发明人之一的肯·汤普森(Ken Thompson)发现可以将正则概念用于计算搜索算法的早期研究;正则表达式的第一个实用应用程序就是 Unix 中的 qed 编辑器。从那时起直至现在,正则表达式都是基于文本的编辑器和搜索工具中的一个重要部分。

二、应用场景

在正则表达式发展起来之前,对于搜索和替换文本这种需求,通常要求提供与预期搜索结果匹配的确切文本。这种「要求提供确切文本」的检索技术不但缺乏足够的灵活性,而且,对于某些特殊检索需求完全不能胜任。

通过使用正则表达式,则可以:

三、正则表达式语法

正则表达式描述了一种字符串匹配的模式,可以用来检查一段文本(或字符串)是否含有某种子字符串,并且提供了可以将匹配的子字符串替换成符合另一种字符串的功能。

正则表达式是由普通字符(例如字符 a 到 z)以及特殊字符(也称为元字符)组成的文字模式。模式描述了在检索文本时要匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。

1、普通字符

正则表达式中的普通字符,包括字母(大写和小写)、数字、汉字、下划线,以及没有特殊定义的标点符号。这些普通字符,在匹配一个字符串的时候,严格匹配与之相同的一个字符。

用法和示例:

字符模式 含义
/A/ 匹配单个字符 A。如:/m/ 模式可以匹配字符串 memory 中出现的所有 m 字符
/ABC/ 匹配字符串 ABC。如模式 /from/,在匹配字符串 select * from user 时,匹配的结果是 from
/[ABC]/ 匹配中括号里面的所有出现的字符。如 [irnb] 匹配字符串 npm run build 中所有的 n r b i 字母。
/[^ABC]/ 和 /[ABC]/ 模式正好相反,它是匹配除了中括号里面的字符以外的所有其它字符。
/[A-Z]/ 该模式表示匹配一个范围。如:[A-Z] 表示匹配所有大写字母;[a-z] 匹配所有小写字母;[0-9] 表示匹配所有数字。

注:在没有特殊限定符配合的情况下,均是指定匹配一个字符。

2、转义字符

在正则表达式中,也可以使用转义字符。常见的转义字符有:

另外,有一些标点符号在正则表达式中有特殊的含义,如:.^$ 等。当需要匹配这些符号时,需要在符号前面添加反斜杠 \ 进行转义。例如:小数点 . 在正则表达式中表示匹配任意字符,如果需要严格匹配 .,则需要对其进行转义,即使用 . 表示 . 本身。

说明:除了正则表达式支持转义字符外,在 Web 开发中接触较多的 HTML 也提供了对转义字符的支持。关于 HTML 中的转义字符,可以参考 HTML 转义字符 大全。

3、表示一类字符的字符

在正则表达式中,一些特殊的模式可以表示匹配一类字符中的任意一个字符。比如,表达式 \d 可以匹配任意一个数字,等价于 [0-9]。

下表列出了常见的可以表示一类字符的字符。

模式 含义
\d 匹配任意一个数字,即 0-9 之间的任意一个数字
\w 匹配任意一个字母、数字或下划线,也就是 A-Z、a-z、0-9 和 _ 中的一个
\s 匹配任何空白字符,包括空格、制表符、换页符等
\S 和 \s 功能相反,它匹配任何非空白字符
. 匹配除换行符 \n 以外的任意一个字符

4、匹配次数限定符

匹配次数限定符,是用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配条件。这些用于表示匹配次数的限定符包括:

限定符 含义
* 匹配 0 次或多次它前面的子表达式。如:go*d 能匹配 gd、god 以及 good
+ 匹配 1 次或多次它前面的子表达式。如:spe*d 能匹配 sped、speed 以及 speeed,但不能匹配 spd
? 匹配 0 次或 1 次它前面的子表达式。如:t(ea)?m,可以匹配 tm,也可以匹配 team。注:可以把 ? 限定符理解为 {0,1}
该表达式使用了大括号,括号中间的 n 是一个非负整数,表示匹配 n 次它前面的子表达式。如:Macbo{2}k,不能匹配 Macbok,因为只出现了一次 o,但是可以匹配 Macbook 中的 2 个 o
{n,} 大括号中间的 n 是一个非负整数,该表达式表示至少匹配 n 次子表达式。如:ht{2,}p,不能匹配 htp 中的 t,但可以匹配 http、htttp、httttp,因为 t 出现了 2 次及以上
{n,m} 在该表达式中,n 和 m 均为非负整数(要求 n <= m),其含义是对于它前面的子表达式,最少匹配 n 次,最多匹配 m 次。如:[0-9]{5,11} 这个表达式,表示对于数字 0-9,要求最少 5 位,最多 11 位才能匹配成功。呐,这不是 QQ 号码的正则表达式嘛!
特别说明:
*、+ 和 ? 限定符都是贪婪匹配的,因为它们会尽可能多的匹配文字,只有在它们的后面再加一个 ? 符号,就可以实现非贪婪或最小匹配。

下面,我们以匹配 HTML 文档中的 H1 标签为例,对贪婪匹配和非贪婪匹配进行说明。

H1 标签内容如下:<h1>独特工具箱</h1>。如果我们要匹配 h1 标签,那么:

贪婪匹配使用的正则表达式是:/<.*>/。该表达式将从开始的小括号 < 开始一直搜索,直到 h1 结束标签的那个大括号 > 才结束。也就是说,/<.*>/ 这个表达式将匹配从开始的 <h1> 标签到结束的 </h1> 为止。
非贪婪匹配使用的正则表达式是:/<.*?>/。该表达式只会匹配开始的那个 <h1> 标签,不会再往后面继续检索了。

5、定位符

定位符用来描述字符串或单词的边界,使你能够将正则表达式固定到行首或行尾。正则表达式的定位符是一个功能十分强大的特性,通过定位符,可以方便地检索指定位置的单词。

正则表达式的定位符有:^、$、\b 和 \B,下表对这几个定位符进行了说明。

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

例如,正则表达式 ^http:// 表示对于待检索的字符串,要求以 http:// 开头,才能正确匹配;而对于 .php$ 这个正则表达式,要求待检索待字符串必须以 .php 结尾才能正确匹配。

特别说明:

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

6、分组和选择

正则表达式也提供了分组和选择的功能。其中,圆括号 () 表示捕获分组,并且可以单独得到通过 () 匹配到的内容;| 表示选择,它左右两边的子表达式是一种“或”关系,即被 | 分隔的子表达式,只要其中之一满足匹配条件,则匹配成功。

7、正向预查和反向预查

由分组衍生出正向预查和反向预查两个概念。

正向预查

正向预查,是指在任何开始匹配圆括号内的正则表达式模式的位置来匹配搜索字符串,其语法是在子模式内部前面加 ?=,意思是:1、要匹配的文本必须满足此子模式前面的表达式;2、此子模式不参与匹配。

例如,我们需要在一段文本中查找 Windows 字符串,并且要求只查找 Windows 后面的版本号是数字的情况,不能是字母。也就是说,我们希望查找 Winodws 7、Windows 10 这种版本号是数字的情况,而忽略 Windows NT、Windows XP、Windows Vista 这种版本号是字母的情况。

那么,基于上述要求,可以通过 Windows(?= [\d.]+\b) 这个正则表达式来满足该需求。

反向预查

反向预查,指在任何结束的地方匹配该正则表达式模式的位置来匹配搜索字符串,其语法是在子模式内部前面加 ?<=,意思是:1、要匹配的文本必须满足此子模式后面的表达式;2、此子模式不参与匹配。

例如,我们要匹配下面这段文本中属于 CNY 的金额(不含 CNY):

CNY: 128.04
USD: 22.5
USD: 23.5
HKD: 1533.5
CNY: 23.78

要达到上述要求,正则表达式正确的写法是:(?<=CNY: )\d+.\d+。

除了正向预查和反向预查,还有对应的正向否定预查 ?! 和反向否定预查 ?<!,有兴趣的可以自行查找资料深入了解其用法。

附 2:常用正则表达式

下面列出了我们日常开发中常用的正则表达式,希望对你有用。

1、匹配电子邮箱地址

\w[-\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\.)+[A-Za-z]{2,14}

2、匹配 URL

https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)

3、匹配十六进制颜色

#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})

4、匹配国内手机号码

1([38][0-9]|4[579]|5[0-3,5-9]|6[6]|7[0135678]|9[89])\d{8}

5、匹配国内 18 位身份证号码

\d{17}[\d|x]

6、匹配 IPv4 地址

(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)

7、匹配 IPv6 地址

(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))

8、匹配 时:分:秒 时间

([01]?\d|2[0-3]):[0-5]?\d:[0-5]?\d

9、匹配 年-月-日 日期

(([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29)

10、匹配汉字

[\u4e00-\u9fa5]

11、匹配车牌号(包括新能源汽车车牌)

^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领]{1}[A-HJ-NP-Z]{1}(?:(([0-9]{5}[DF])|([DF][A-HJ-NP-Z0-9][0-9]{4}))|[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]{1})$