正则表达式必知必会(修订版)
一、匹配单个字符
- . (英文句号)可以匹配任何单个字符(在绝大多数实现里,除换行符)
- \ 用来对字符进行转义(在正则表达式里,有特殊含义的字符总是以\字符开头)
二、匹配一组字符
- 元字符[和]用来定义一个字符集合,其含义是必须匹配该集合里的字符之一
- 元字符 - (连字符)可以表示字符区间
- 字符集合里可以用元字符 ^ 求反
三、使用元字符
- 匹配数字
元字符 | 说明 |
---|---|
\d | [0-9] |
\D | [^0-9] |
2. 匹配字母和数字
元字符 | 说明 |
---|---|
\w | [a-zA-Z0-9_] |
\W | [^a-zA-Z0-9_] |
3. 匹配空白字符
元字符 | 说明 |
---|---|
\s | [\f\n\r\t\v] |
\S | [^\f\n\r\t\v] |
4. 匹配16进制(\x)或八进制(\0)数值
5. POSIX字符类(JavaScript不支持)
四、重复次数匹配
- 简易匹配
元字符 | 说明 |
---|---|
+ | 至少一次 |
* | 零次或多次 |
? | 零次或一次 |
2. 精确匹配
元字符 | 说明 |
---|---|
{3} | 3次 |
{3,5} | 最少3次,最多5次 |
{3, } | 至少3次 |
3. 防止过度匹配
贪婪型(greedy)元字符 | 懒惰型元字符(nongreedy) |
---|---|
* | *? |
+ | +? |
{n, } | {n, }? |
五、位置匹配
\b 指定一个单词边界(匹配位置,不匹配任何字符)
\B 不匹配单词边界
^ 指定字符串的开头
$ 匹配字符串的结束
(?m) 与 ^ 和 $ 配合使用,还将匹配在换行符处开头和结尾的字符串(用在最前面)
(?m)^\s*//.*$
查找JavaScript代码里的行注释
六、使用子表达式
子表达式必须用 ( 和 ) 定义
常见用途:
- 对重复次数元字符的作用对象做出精确的设定和控制
- 对 | 操作符的 OR 条件做出准确定义
- 子表达式允许嵌套
示例:匹配IP地址
简易型:
(\d{1,3}\.){3}\d{1,3}
完善型(注意 | 的使用):
(((25[0-5])|(2[0-4]\d)|(1\d{2})|(\d{1,2}))\.){3}((25[0-5])|(2[0-4]\d)|(1\d{2})|(\d{1,2}))
七、回溯引用:前后一致匹配
可以将回溯引用想象成变量,\1 代表模式里的第一个子表达式
- 不同实现的语法可能有差异
- 某些实现可能支持命名捕获功能(如.NET),鼓励使用
回溯引用在替换操作中的使用
注意不同实现中的差异(Java使用 $ )
// 电话号码重新排版
正则表达式:
(\d{3})(-)(\d{3})(-)(\d{4})
替换式:
($1) $3-$5
大小写转换
元字符 说明 \E 结束\L或\U转换 \l 把下一个字符转换为小写 \L 把\L到\E之间的字符转换为小写 \u 把下一个字符转换为大写 \U 把\U到\E之间的字符转换为大写
八、前后查找
向前查找(
(?=...)
)// 提取URL地址的协议名(不消费(consume) : )
.+(?=:)
向后查找(
(?<=...)
)(JavaScript可能不支持)// 提取价格中的数值部分
(?<=\$)[0-9.]+
对前后查找取非
操作符 | 说明 |
---|---|
(?=) | 正向前查找 |
(?!) | 负向前查找 |
(?<=) | 正向后查找 |
(?<!) | 负向后查找 |
九、嵌入条件
回溯引用条件
满足时的语法:
(?(backreference)true-regex)
查找文本中的
<img>
标签,如果包含在<a>
之间,则匹配出<a>
(<[Aa]\s+[^>]+>\s+)?<[Ii][Mm][Gg]\s+[^>]+>(?(1)\s*</[Aa]>)
不满足时的语法:
(?(backreference)true-regex|false-regex)
匹配北美电话格式
(\()?\d{3}(?(1)\)|-)\d{3}-\d{4}
前后查找条件
语法: 将回溯引用时的编号替换为前后查找表达式
匹配美国的ZIP编码
\d{5}(?(?=-)-\d{4})