正则表达式

Posted by Marlin on July 9, 2025

本文大量参照了正则表达式30分钟入门教程,并结合自己的理解进行了补充和修改。

正则表达式(Regular Expression,简称Regex或RegExp)是一种用于描述、匹配和处理文本模式的工具,它通过特定的语法规则来定义字符串的匹配模式,广泛应用于文本搜索、替换、验证等场景。以下是关于正则表达式的详细介绍:

一、核心概念与作用

  1. 模式描述
    用简洁的符号组合描述字符串的规则,例如:
    • \d+ 匹配1个或多个数字(如 12345
    • [a-z]+@[a-z]+\.[a-z]+ 匹配邮箱格式(如 user@example.com
  2. 主要作用
    • 文本匹配:从文本中提取符合特定模式的内容(如提取日志中的IP地址)。
    • 格式验证:验证输入是否符合规范(如手机号、URL地址)。
    • 文本替换:批量修改文本中的特定模式(如将所有邮箱地址替换为[敏感信息])。
    • 数据清洗:过滤或整理非结构化文本(如从网页中提取纯文字)。

二、基础语法与符号

1. 字符匹配

符号 含义 示例
普通字符 匹配自身(如 a 匹配 a5 匹配 5 abc 匹配 abc
. 匹配任意单个字符(除换行符外) a.c 匹配 abca0c
\d 匹配数字(等价于 [0-9] \d+ 匹配 123
\w 匹配字母、数字或下划线(等价于 [a-zA-Z0-9_] \w+ 匹配 user123
\s 匹配空白字符(空格、制表符等) a\sb 匹配 a b
[abc] 匹配方括号内任意一个字符(abc [1-3] 匹配 123
[^abc] 匹配不在方括号内的任意字符 [^0-9] 匹配非数字

2. 数量限定

符号 含义 示例
* 匹配前面的元素 0 次或多次 a* 匹配空字符串或 aaa
+ 匹配前面的元素 1 次或多次 a+ 匹配 aaa
? 匹配前面的元素 0 次或 1 次 a? 匹配空字符串或 a
{n} 精确匹配前面的元素 n 次 a{2} 匹配 aa
{n, m} 匹配前面的元素至少 n 次,最多 m 次 a{1,3} 匹配 aaaaaa

3. 位置匹配

符号 含义 示例
^ 匹配字符串开头 ^abc 匹配以 abc 开头的字符串
$ 匹配字符串结尾 abc$ 匹配以 abc 结尾的字符串
\b 匹配单词边界(字母与非字母的交界处) \bcat\b 匹配独立的 cat 单词

三、经典示例与应用场景

1. 邮箱验证

  • 模式:^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
  • 解释:
    • [a-zA-Z0-9._%+-]+:匹配邮箱前缀(字母、数字、下划线等)
    • @:匹配@符号
    • [a-zA-Z0-9.-]+:匹配域名主体
    • \.[a-zA-Z]{2,}:匹配域名后缀(如 .com.cn

2. 手机号验证(中国大陆)

  • 模式:^1[3-9]\d{9}$
  • 解释:以 1 开头,第二位为 3-9 中的数字,后续接 9 位数字(如 13812345678)。

3. URL提取

  • 模式:https?://[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}(/[^\s]*)?
  • 解释:匹配 httphttps 开头的网址(如 https://example.com/page)。

四、正则表达式的特点与注意事项

  1. 特点
    • 灵活性:几乎可以描述任何文本模式,但语法复杂。
    • 效率差异:复杂模式可能导致匹配效率低下(如嵌套量词可能引发“回溯爆炸”)。
    • 跨语言支持:大多数编程语言(Python、Java、JavaScript等)和文本工具(Notepad++、VS Code)都支持正则表达式,但语法可能略有差异。
  2. 注意事项
    • 转义字符:在正则中,\ 用于转义特殊符号(如匹配 \ 需写作 \\),而在编程语言中可能需要双重转义(如 Python 中写作 r'\\')。
    • 贪婪与非贪婪:默认情况下,量词(*+ 等)是“贪婪”的(尽可能多匹配),添加 ? 可变为非贪婪模式(如 a.*?b 匹配最短的 a...b)。
    • 测试工具:建议使用在线工具(如 Regex101)验证模式,避免手写错误。

五、代码实现示例(Python)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import re

# 1. 匹配邮箱
email_pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
emails = ['user@example.com', 'invalid@.com', 'name@domain.co.uk']
for email in emails:
    if re.match(email_pattern, email):
        print(f'"{email}" 是有效邮箱')
    else:
        print(f'"{email}" 不是有效邮箱')

# 2. 提取文本中的URL
text = "访问 https://example.com 获取更多信息,或联系 http://support.site"
url_pattern = r'https?://[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}(/[^\s]*)?'
urls = re.findall(url_pattern, text)
print("提取的URL:", urls)

# 3. 替换文本中的敏感词
text = "请联系客服12345678901,邮箱为user@company.com"
phone_pattern = r'1[3-9]\d{9}'
masked_text = re.sub(phone_pattern, '[手机号已隐藏]', text)
print("替换后的文本:", masked_text)

正则表达式是文本处理的强大工具,熟练掌握其语法和应用场景,能大幅提升数据处理和文本分析的效率。如果需要更复杂的模式,建议结合具体需求逐步构建和测试。