选择或分支关系
用圆括号将所有选择项括起来,相邻的选择项之间用|
分隔。
但用圆括号会有一个副作用,使相关的匹配会被缓存,此时可用?:
放在第一个选项前来消除这种副作用。
\d{5}-\d{4}|\d{5}
这个表达式用于匹配美国的邮政编码。
美国邮编的规则是5位数字,或者用连字号间隔的9位数字。之所以要给出这个例子是因为它能说明一个问题:使用分枝条件时,要注意各个条件的顺序。
如果你把它改成\d{5}|\d{5}-\d{4}
的话,那么就只会匹配5位的邮编(以及9位邮编的前5位)。
原因是匹配分枝条件时,将会从左到右地测试每个条件,如果满足了某个分枝的话,就不会去再管其它的条件了。
?:
是非捕获元之一,
还有两个非捕获元是 ?=
和 ?!
,这两个还有更多的含义。
前者为正向预查,在任何开始匹配圆括号内的正则表达式模式的位置来匹配搜索字符串。
后者为负向预查,在任何开始不匹配该正则表达式模式的位置来匹配搜索字符串。
example:
industr(?:y|ies)
相当于 industry|industries
各种预查
语法 | 中文名 | 英文名 |
---|---|---|
(?=pattern) |
正向肯定预查 | look ahead positive assert |
(?!pattern) |
正向否定预查 | look ahead negative assert |
(?<=pattern) |
反向肯定预查 | look behind positive assert |
(?<!pattern) |
反向否定预查 | look behind negative assert |
正向肯定预查
(?=pattern)
在任何匹配pattern
的字符串开始处匹配查找字符串。
这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用
例如,Windows(?=95|98|NT|2000)
能匹配 Windows2000
中的 Windows
,
但不能匹配 Windows3.1
中的 Windows
。
预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
举例来说,
Windows(?=95|98|NT|2000)\d+
可以匹配 整个 Windows2000
注意: 在这里, Windows(?=95|98|NT|2000)
中的|
实际上相当于数学中的 or
正向否定预查
(?!pattern)
在任何不匹配pattern
的字符串开始处匹配查找字符串。
这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。
例如Windows(?!95|98|NT|2000)
能匹配Windows3.1
中的Windows
,
但不能匹配Windows2000
中的Windows
。
预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
注意: 在这里, Windows(?!95|98|NT|2000)
中的|
实际上相当于数学中的 And
而不是or
,与上文相比不同。即同一个|
符号在肯定预查和否定预查中的数学意义不同
反向肯定预查
\(?<=pattern)
与正向肯定预查类似,只是方向相反。
例如,(?<=95|98|NT|2000)Windows
能匹配 2000Windows
中的Windows
,
但不能匹配 3.1Windows
中的 Windows
。
反向否定预查
(?<!pattern)
反向否定预查,与正向否定预查类似,只是方向相反。
例如(?<!95|98|NT|2000)Windows
能匹配3.1Windows
中的Windows
,但不能匹配2000Windows
中的Windows
。
反向引用
对一个正则表达式模式或部分模式两边添加圆括号将导致相关匹配存储到一个临时缓冲区中,
所捕获的每个子匹配都按照在正则表达式模式中从左到右出现的顺序存储。
缓冲区编号从 1
开始,最多可存储 99
个捕获的子表达式。
每个缓冲区都可以使用 \n
访问,其中 n
为一个标识特定缓冲区的 一位或两位十进制数。
可以使用非捕获元字符 ?:
、?=
或 ?!
来重写捕获,忽略对相关匹配的保存。
example
相同的相邻单词
反向引用的最简单的、最有用的应用之一,
是提供查找文本中两个相同的相邻单词的匹配项的能力。
以下面的句子为例:
Is is the cost of of gasoline going up up?
上面的句子很显然有多个重复的单词。
下面的正则表达式使用单个子表达式来定位这个句子:
/
\b([a-z]+) \1\b
/ig;
%%
result: Is is,of of,up up
说明:
- 捕获的表达式,正如
[a-z]+
指定的,包括一个或多个字母。 - 正则表达式的第二部分是对以前捕获的子匹配项的引用,即,单词的第二个匹配项正好由括号表达式匹配。\1 指定第一个子匹配项。
- 单词边界元字符确保只检测整个单词。否则,诸如
is issued
或this is
之类的词组将不能正确地被此表达式排除。 - 正则表达式后面的全局标记
g
指定将该表达式应用到输入字符串中能够查找到的尽可能多的匹配。 - 表达式的结尾处的不区分大小写
i
标记指定不区分大小写。 - 多行标记指定换行符的两边可能出现潜在的匹配。
example
URI 分解
反向引用还可以将通用资源指示符 (URI) 分解为其组件。
假定你想将下面的 URI 分解为协议(ftp、http 等等)、域地址和页/路径:
http://www.runoob.com:80/html/html-tutorial.html
下面的正则表达式提供该功能:
/
(\w+):\/\/
([^/:]+)
(:\d*)?
([^# ]*)
/;
- 第一个括号子表达式捕获 Web 地址的协议部分。该子表达式匹配在冒号和两个正斜杠前面的任何单词。
- 第二个括号子表达式捕获地址的域地址部分。子表达式匹配
:
和/
之后的一个或多个字符。 - 第三个括号子表达式捕获端口号(如果指定了的话)。该子表达式匹配冒号后面的零个或多个数字。只能重复一次该子表达式。(当
?
紧跟在任何一个其他限制符后面时,匹配模式是非贪婪的) - 最后,第四个括号子表达式捕获 Web 地址指定的路径和
/
或页信息。该子表达式能匹配不包括 # 或空格字符的任何字符序列。
将正则表达式应用到上面的 URI,各子匹配项包含下面的内容:
第一个括号子表达式包含 http
第二个括号子表达式包含 www.runoob.com
第三个括号子表达式包含 :80
第四个括号子表达式包含 /html/html-tutorial.html
网友评论