集合和范围 [...]
在方括号 […]
中的几个字符或者字符类意味着“搜索给定的字符中的任意一个”。
集合
比如说,[eao]
意味着查找在 3 个字符 'a'
、'e'
或者 `‘o’ 中的任意一个。
这被叫做一个集合。集合可以在正则表达式中和其它常规字符一起使用。
// 查找 [t 或者 m],然后再匹配 “op”
alert( "Mop top".match(/[tm]op/gi) ); // "Mop", "top"
请注意尽管在集合中有多个字符,但它们在匹配中只会对应其中的一个。
所以下面的示例并不会匹配上:
// 查找 “V”,然后匹配 [o 或者 i],之后再匹配 “la”
alert( "Voila".match(/V[oi]la/) ); // null,并没有匹配上
这个模式会做以下假设:
V
,- 然后匹配其中的一个字符
[oi]
, - 然后匹配
la
,
所以可以匹配上 Vola
或者 Vila
。
范围
方括号也可以包含字符范围。
比如说,[a-z]
会匹配从 a
到 z
范围内的字母,[0-5]
表示从 0
到 5
的数字。
在下面的示例中,我们会查询首先匹配 "x"
字符,再匹配两个数字或者位于 A
到 F
范围内的字符。
alert( "Exception 0xAF".match(/x[0-9A-F][0-9A-F]/g) ); // xAF
[0-9A-F]
表示两个范围:它搜索一个字符,满足数字 0
到 9
或字母 A
到 F
。
如果我们还想查找小写字母,则可以添加范围 a-f
:[0-9A-Fa-f]
。或添加标志 i
。
我们也可以在 […]
里面使用字符类。
例如,如果我们想要查找单词字符 \w
或连字符 -
,则该集合为 [\w-]
。
也可以组合多个类,例如 [\s\d]
表示 “空格字符或数字”。
例如:
- \d —— 和
[0-9]
相同, - \w —— 和
[a-zA-Z0-9_]
相同, - \s —— 和
[\t\n\v\f\r ]
外加少量罕见的 unicode 空格字符相同。
示例:多语言 \w
由于字符类 \w
是简写的 [a-zA-Z0-9_]
,因此无法找到中文象形文字,西里尔字母等。
我们可以编写一个更通用的模式,该模式可以查找任何语言中的文字字符。这很容易想到就 Unicode 属性:[\p{Alpha}\p{M}\p{Nd}\p{Pc}\p{Join_C}]
。
让我们理解它。类似于 \w
,我们在制作自己的一套字符集,包括以下 unicode 字符:
Alphabetic
(Alpha
) —— 字母,Mark
(M
) —— 重读,Decimal_Number
(Nd
) —— 数字,Connector_Punctuation
(Pc
) —— 下划线'_'
和类似的字符,Join_Control
(Join_C
) —— 两个特殊代码200c
and200d
,用于连字,例如阿拉伯语。
使用示例:
let regexp = /[\p{Alpha}\p{M}\p{Nd}\p{Pc}\p{Join_C}]/gu;
let str = `Hi 你好 12`;
// finds all letters and digits:
alert( str.match(regexp) ); // H,i,你,好,1,2
当然,我们可以编辑此模式:添加 unicode 属性或删除它们。文章 Unicode:修饰符 “u” 和 class \p{...} 中包含了更多 Unicode 属性的细节。
Edge 和 Firefox 不支持 Unicode 属性Edge 和 Firefox 尚未实现 Unicode 属性 p{…}
。如果确实需要它们,可以使用库 XRegExp。
或者只使用我们想要的语言范围的字符,例如西里尔字母 [а-я]
。
排除范围
除了普通的范围匹配,还有类似 [^…]
的“排除”范围匹配。
它们通过在匹配查询的开头添加插入符号 ^
来表示,它会匹配所有除了给定的字符之外的任意字符。
比如说:
[^aeyo]
—— 匹配任何除了'a'
、'e'
、'y'
或者'o'
之外的字符。[^0-9]
—— 匹配任何除了数字之外的字符,也可以使用\D
来表示。[^\s]
—— 匹配任何非空字符,也可以使用\S
来表示。
下面的示例查询除了字母,数字和空格之外的任意字符:
alert( "alice15@gmail.com".match(/[^\d\sA-Z]/gi) ); // @ and .
在 […] 中不转义
通常当我们的确需要查询点字符时,我们需要把它转义成像 \.
这样的形式。如果我们需要查询一个反斜杠,我们需要使用 \\
。
在方括号表示中,绝大多数特殊字符可以在不转义的情况下使用:
- 表示一个点符号
'.'
。 - 表示一个加号
'+'
。 - 表示一个括号
'( )'
。 - 在开头或者结尾表示一个破折号(在这些位置该符号表示的就不是一个范围) `pattern:’-’。
- 在不是开头的位置表示一个插入符号(在开头位置该符号表示的是排除)
'^'
。 - 表示一个开口的方括号符号
'['
。
换句话说,除了在方括号中有特殊含义的字符外,其它所有特殊字符都是允许不添加反斜杠的。
一个在方括号中的点符号 "."
表示的就是一个点字符。查询模式 [.,]
将会寻找一个为点或者逗号的字符。
在下面的示例中,[-().^+]
会查找 -().^+
的其中任意一个字符:
// 并不需要转义
let reg = /[-().^+]/g;
alert( "1 + 2 - 3".match(reg) ); // 匹配 +,-
。。。但是如果你为了“以防万一”转义了它们,这也不会有任何问题:
//转义其中的所有字符
let reg = /[\-\(\)\.\^\+]/g;
alert( "1 + 2 - 3".match(reg) ); // 仍能正常工作:+,-
范围和标志“u”
如果集合中有代理对(surrogate pairs),则需要标志 u
以使其正常工作。
例如,让我们在字符串