在正则表达式中,[]
(字符类)和|
(或操作符)都用于表示“或”的关系,但它们的用法和语义有本质区别:
一、字符类 []
作用
匹配方括号内任意一个字符,只能匹配单个字符。
语法规则
- 普通字符:直接列出需要匹配的字符。
- 例如:
[abc]
匹配a
、b
或c
中的任意一个字符。
- 例如:
- 范围表示:使用连字符
-
表示字符范围。- 例如:
[0-9]
匹配任意数字,[a-zA-Z]
匹配任意字母。
- 例如:
- 否定:在方括号内以
^
开头,表示匹配不在方括号内的字符。- 例如:
[^0-9]
匹配任意非数字字符。
- 例如:
示例
[aeiou]
:匹配任意元音字母。[0-9a-fA-F]
:匹配十六进制数字(0-9、a-f、A-F)。[^ ]
:匹配任意非空格字符。
二、或操作符 |
作用
匹配多个子表达式中的任意一个,可以匹配多个字符组成的字符串。
语法规则
- 分隔子表达式:用
|
分隔多个子表达式,表示“或”关系。- 例如:
cat|dog
匹配cat
或dog
。
- 例如:
- 优先级:
|
的优先级较低,通常需要用括号()
明确分组。- 例如:
a(b|c)
匹配ab
或ac
,而不是b
或c
。
- 例如:
示例
(Mr|Mrs|Ms)\.
:匹配Mr.
、Mrs.
或Ms.
。\d{3}-\d{4}|\+\d{1,3}\s\d{10}
:匹配123-4567
格式的电话号码,或+86 1234567890
格式的国际号码。
三、关键区别对比
| 特性 | 字符类 []
| 或操作符 |
|
|------------------------|-------------------------------------|--------------------------------------|
| 匹配单位 | 单个字符 | 整个子表达式(可以是多个字符) |
| 示例 | [abc]
匹配 a
, b
, 或 c
| abc|def
匹配 abc
或 def
|
| 否定形式 | [^...]
表示取反 | 无直接否定形式,需用 (?!...)
零宽断言 |
| 常用场景 | 字符级的多选(如密码强度检查) | 字符串级的多选(如匹配不同单词) |
| 性能 | 通常更快(直接索引字符集) | 较慢(需依次尝试多个子表达式) |
四、常见误区
错误混用:
- 错误:
[cat|dog]
(期望匹配cat
或dog
) - 正确:
(cat|dog)
或cat|dog
(|
分隔完整子表达式)
- 错误:
过度使用
|
:- 错误:
a|b|c|d
(匹配单个字符时效率低) - 正确:
[abcd]
(字符类更高效)
- 错误:
五、正则表达式示例
1. 验证邮箱域名
(qq|gmail|outlook)\.com # 匹配 qq.com、gmail.com 或 outlook.com
2. 匹配HTML标签
<(div|p|h[1-6])> # 匹配 <div>、<p> 或 <h1>~<h6>
3. 匹配日期格式
\d{4}(-|/)\d{2}(-|/)\d{2} # 匹配 2023-06-26 或 2023/06/26
六、性能注意事项
- 字符类
[]
的匹配速度通常快于|
,因为它直接检查字符是否在预定义集合中。 - 或操作符
|
可能导致回溯(backtracking),尤其是子表达式较长时。例如:(abc|def|ghi)+
可能在匹配失败时多次尝试不同分支。
在需要高效匹配单个字符的多选情况时,优先使用字符类 []
。