正则表达式,又称规则表达式,是一种文本模式,通常用来检索、替换和控制文本。在计算机科学中,是指一个用来描述或者匹配一系列符合某个句法规则的字符串的单个字符串。
语法
选择
用圆括号将所有选择项括起来,相邻的选择项之间用|分隔。但用圆括号会有一个副作用,是相关的匹配会被缓存,此时可用 ?:
放在第一个选项前来消除这种副作用。
其中 ?:
是非捕获元之一,还有两个非捕获元是 ?=
和 ?!
,这两个还有更多的含义,前者为正向预查,在任何开始匹配圆括号内的正则表达式模式的位置来匹配搜索字符串,后者为负向预查,在任何开始不匹配该正则表达式模式的位置来匹配搜索字符串。
反向引用
对一个正则表达式模式或部分模式两边添加圆括号将导致相关匹配存储到一个临时缓冲区中,所捕获的每个子匹配都按照在正则表达式模式中从左到右出现的顺序存储。缓冲区编号从 1 开始,最多可存储 99 个捕获的子表达式。每个缓冲区都可以使用 \n
;访问,其中 n
为一个标识特定缓冲区的一位或两位十进制数。
可以使用非捕获元字符 ?:
、?=
或 ?!
来重写捕获,忽略对相关匹配的保存。
反向引用的最简单的、最有用的应用之一,是提供查找文本中两个相同的相邻单词的匹配项的能力。以下面的句子为例:
Is is the cost of of gasoline going up up?
上面的句子很显然有多个重复的单词。如果能设计一种方法定位该句子,而不必查找每个单词的重复出现,那该有多好。下面的正则表达式使用单个子表达式来实现这一点:
/\b([a-z]+) \1\b/gi/
捕获的表达式,正如 [a-z]+ 指定的,包括一个或多个字母。正则表达式的第二部分是对以前捕获的子匹配项的引用,即,单词的第二个匹配项正好由括号表达式匹配。\1
指定第一个子匹配项。字边界元字符确保只检测整个单词。否则,诸如“is issued”或“this is”之类的词组将不能正确地被此表达式识别。
正则表达式后面的全局标记(g)指示,将该表达式应用到输入字符串中能够查找到的尽可能多的匹配。表达式的结尾处的不区分大小写(i)标记指定不区分大小写。多行标记指定换行符的两边可能出现潜在的匹配。
反向引用还可以将通用资源指示符(URI)分解为其组件。假定您想将下面的 URI 分解为协议(ftp、http 等等)、域地址和页/路径:
https://www.w3cschool.cn:80/html/html-tutorial.html/
下面的正则表达式提供该功能:
/(\w+):\/\/([^/:]+)(:\d*)?([^# ]*)/
第一个括号子表达式捕获 Web 地址的协议部分。该子表达式匹配在冒号和两个正斜杠前面的任何单词。第二个括号子表达式捕获地址的域地址部分。子表达式匹配 / 或 : 之外的一个或多个字符。第三个括号子表达式捕获端口号(如果指定了的话)。该子表达式匹配冒号后面的零个或多个数字。只能重复一次该子表达式。最后,第四个括号子表达式捕获 Web 地址指定的路径和/或页信息。该子表达式能匹配不包括 # 或空格字符的任何字符序列。
将正则表达式应用到上面的 URI,各子匹配项包含下面的内容:
第一个括号子表达式包含“https”
第二个括号子表达式包含“www.w3cschool.cn”
第三个括号子表达式包含“:80”
第四个括号子表达式包含“/html/html-tutorial.html”
元字符
.
匹配除换行符之外的任何单个字符。要匹配包括换行符在内的任何字符,请使用像 [.\n]
的模式。
(?:pattern)
匹配 pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用“或”字符(|)来组合一个模式的各个部分是很有用。例如,industr(?:y|ies)
就是一个比 industry|industries
更简略的表达式。
(?=pattern)
正向预查,在任何匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,Windows (?=95|98|NT|2000)
能匹配“Windows 2000”中的“Windows”,但不能匹配“Windows 3.1”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
(?!pattern)
负向预查,在任何不匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如 Windows (?!95|98|NT|2000)
能匹配“Windows 3.1”中的“Windows”,但不能匹配“Windows 2000”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
[xyz]
字符集合。匹配所包含的任意一个字符。例如,[abc]
可以匹配“plain”中的‘a’。
[^xyz]
负值字符集合。匹配未包含的任意字符。例如,[^abc]
可以匹配“plain”中的‘a’。
\cx
匹配由 x 指明的控制字符。例如,\cM
匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的‘c’字符。
\d
匹配一个数字字符。等价于 [0-9]。
\s
匹配任何空白字符,包括空格、制表符、换页符等等。
\w
匹配包括下划线的任何单词字符。等价于 [A-Za-z0-9_]
。
\num
匹配 num,其中 num 是一个正整数。对所获取的匹配的引用。例如,(.)\1
匹配两个连续的相同字符。
匹配规则
^[a-zA-Z0-9_]+$ // 所有包含一个以上的字母、数字或下划线的字符串
^[0-9]+$ // 所有的正数
^\\-?[0-9]+$ // 所有的整数
^\\-?[0-9]*\\.?[0-9]*$ // 所有的小数
示例
下面列出一些正则表达式示例:
正则表达式 | 描述 |
---|---|
/\b([a-z]+) \1\b/gi |
一个单词连续出现的位置。 |
/(\w+):\/\/([^/:]+)(:\d*)?([^# ]*)/ |
将一个URL解析为协议、域、端口及相对路径。 |
/^(?:Chapter|Section) [1-9][0-9]{0,1}$/ |
定位章节的位置。 |
/[-a-z]/ |
A 至 z 共 26 个字母再加一个 - 号。 |
/ter\b/ |
可匹配 chapter,但不能匹配 terminal。 |
/\Bapt/ |
可匹配 chapter,但不能匹配 aptitude。 |
/Windows (?=95|98|NT)/ |
可匹配 Windows 95、Windows 98 或 Windows NT。当找到一个匹配后,从 Windows 后面开始进行下一次的检索匹配。 |
/^\s*$/ |
匹配空行。 |
/\d{2}-\d{5}/ |
验证由两位数字、一个连字符再加 5 位数字组成的 ID 号。 |
/<\s*(\S+)(\s[^>]*)?>[\s\S]*<\s*\/\1\s*>/ |
匹配 HTML 标记。 |