正则表达式(Regular Expression,简称 regex)是一种文本模式匹配的工具,用于在字符串中查找、替换、提取符合特定规则的内容。它就像一种为文本设计的“搜索模式语言”,广泛应用于编程、文本编辑、数据处理等领域。
正则核心概念:
- 1.模式(Pattern)
用一系列特殊字符和普通字符组成的字符串,描述要匹配的文本规则。
示例:
\d{3}-\d{2}-\d{4}
可匹配123-45-6789
(类似身份证号格式)。 - 2.元字符(Metacharacters)
具有特殊含义的字符,例如:
-
.
:匹配任意单个字符(除了换行符) -
*
:匹配前一个字符0次或多次 -
+
:匹配前一个字符1次或多次 -
?
:匹配前一个字符0次或1次 -
\d
:匹配任意数字(等价于[0-9]
) -
\w
:匹配字母、数字或下划线(等价于[a-zA-Z0-9_]
)
-
- 3.字符类(Character Classes)
用方括号
[]
定义一组字符,匹配其中任意一个。示例:
[aeiou]
匹配任意英文元音字母。 - 4.分组与捕获(Grouping)
用
()
将子模式分组,并可提取匹配内容。示例:
(\d{4})-(\d{2})
匹配2023-10
并捕获年份和月份。 - 5.量词(Quantifiers)
指定匹配次数:
-
{n}
:精确匹配 n 次 -
{n,}
:至少 n 次 -
{n,m}
:匹配 n 到 m 次
-
常见用途示例:
场景 |
正则表达式示例 |
匹配内容 |
---|---|---|
邮箱地址验证 |
|
简单匹配 |
提取日期 |
|
从 |
删除HTML标签 |
|
删除 |
查找连续重复单词 |
|
匹配 "the the" 或 "is is" |
编程中的应用(Python示例):
import re
text = "联系客服:400-123-4567 或 800-789-0123"
pattern = r"\d{3}-\d{3}-\d{4}" # 匹配电话号码
# 查找所有匹配
phones = re.findall(pattern, text)
print(phones) # 输出: ['400-123-4567', '800-789-0123']
# 替换内容
new_text = re.sub(pattern, "***-***-****", text)
print(new_text) # "联系客服:***-***-**** 或 ***-***-****"
学习建议:
- 1.从简单模式开始:先掌握基础元字符(如
.
,*
,\d
,[]
)。 - 2.在线工具辅助:使用 Regex101或 RegExr实时测试。
- 3.避免过度复杂:复杂的 regex 可能难以维护,必要时拆分处理。
- 4.注意性能:回溯过多会导致性能问题(如嵌套量词
.*.*
)。
⚠️ 关键警告:
正则表达式 不适合解析复杂结构化数据(如 HTML、XML),此时应使用专用解析器(如 BeautifulSoup、XPath)。
掌握 regex 能大幅提升文本处理效率,但需平衡可读性与复杂性。遇到棘手问题时,拆分为多个简单步骤常比写一个巨型表达式更稳妥!
断言
1. 边界类断言
- **
^
(开头)**: 匹配字符串起始位置。^abc // 匹配以"abc"开头的字符串
- **
$
(结尾)**: 匹配字符串结束位置。abc$ // 匹配以"abc"结尾的字符串
- **
\b
(单词边界)**: 匹配单词与非单词字符(如空格、标点)之间的位置。\bcat\b // 匹配独立的单词"cat"(前后无其他字母)
- **
\B
(非单词边界)**: 匹配非单词边界(如连续字母之间)。\Bcat\B // 匹配"scatter"中的"cat"(前后均有字母)
2. 前瞻断言(Lookahead)
- **
(?=...)
(正向前瞻)**: 后续必须匹配表达式。a(?=bc) // 匹配后面紧跟着"bc"的"a"(如"abc")
- **
(?!...)
(负向前瞻)**: 后续不能匹配表达式。a(?!bc) // 匹配后面不是"bc"的"a"(如"ad")
3. 后顾断言(Lookbehind)
- **
(?<=...)
(正向后顾)**: 前面必须匹配表达式。(?<=a)bc // 匹配前面是"a"的"bc"(如"abc")
- **
(?<!...)
(负向后顾)**: 前面不能匹配表达式。(?<!a)bc // 匹配前面不是"a"的"bc"(如"xbc")
※ 注意:后顾断言在部分编程语言中不支持复杂表达式(如 Python 需固定长度,JavaScript 部分版本有限制)。
4. 示例应用场景
- 验证密码强度(至少一个大写字母、数字):
^(?=.*[A-Z])(?=.*\d).{8,}$ // 匹配8位以上,且含大写字母和数字的密码
- 提取不在引号中的关键词:
\bkeyword\b(?=(?:[^"]*"[^"]*")*[^"]*$) // 匹配未在双引号内的"keyword"
- 匹配特定分隔符之间的内容:
(?<=@)\w+ // 匹配"@username"中的"username"
注意事项
- 兼容性:后顾断言(Lookbehind)在旧环境(如 IE)中可能不被支持。
- 零宽度:断言只验证位置,不占用字符。
- 性能:复杂断言可能影响正则效率,建议测试优化。
通过合理使用断言,可以精确控制匹配逻辑,处理复杂边界条件或依赖上下文的内容验证