Skip to content

Latest commit

 

History

History
266 lines (205 loc) · 8.48 KB

File metadata and controls

266 lines (205 loc) · 8.48 KB

正则表达式完整语法总结

基于菜鸟教程参考,按照重要性和使用频率组织整理

🔥 核心基础语法 (95% 使用场景)

1. 普通字符与字符类

语法 描述 示例 匹配结果
[ABC] 匹配方括号内任意字符 [aeiou] "google"中的 o, e, o, o, a
[^ABC] 匹配除方括号内字符外的任意字符 [^aeiou] "google"中的 g, g, l
[A-Z] 匹配大写字母A到Z [A-Z] "Hello"中的 H
[a-z] 匹配小写字母a到z [a-z] "Hello"中的 e, l, l, o
[0-9] 匹配数字0到9 [0-9] "2023"中的 2, 0, 2, 3
. 匹配除换行符外的任意单个字符 a.c "abc", "a1c", "a c"
[\s\S] 匹配所有字符(包括换行符) [\s\S]+ 任意字符串,包括多行
\w 匹配字母、数字、下划线 \w+ "hello123", "user_name"
\W 匹配非字母、数字、下划线 \W+ " ", "!", "@"
\d 匹配任意数字(0-9) \d+ "123", "4567"
\D 匹配非数字字符 \D+ "abc", "!@#"

2. 量词限定符

语法 描述 等价形式 示例 匹配结果
* 匹配前面元素0次或多次 {0,} zo* "z", "zo", "zoo"
+ 匹配前面元素1次或多次 {1,} zo+ "zo", "zoo" (不包括"z")
? 匹配前面元素0次或1次 {0,1} do(es)? "do", "does"
{n} 匹配前面元素恰好n次 - o{2} "food"中的"oo"
{n,} 匹配前面元素至少n次 - o{2,} "foooood"中的所有o
{n,m} 匹配前面元素n到m次 - o{1,3} "fooooood"中的前3个o

3. 贪婪 vs 非贪婪匹配

语法 描述 示例 匹配结果
* 贪婪匹配(尽可能多) /<.*>/ <h1>标题</h1> (整个标签)
*? 非贪婪匹配(尽可能少) /<.*?>/ <h1> (仅开始标签)
+ 贪婪匹配 /.+/ "abc123" (整个字符串)
+? 非贪婪匹配 /.+?/ "a" (仅第一个字符)

🚀 定位符与边界 (80% 使用场景)

语法 描述 示例 匹配结果
^ 匹配字符串开始位置 ^abc "abc123", "abcdef"
$ 匹配字符串结束位置 abc$ "123abc", "defabc"
\b 匹配单词边界 \bword\b "word" (不包括"wording")
\B 匹配非单词边界 \Bword\B "swordsman"中的"word"

📊 分组与选择 (70% 使用场景)

1. 基本分组

语法 描述 示例 说明
(pattern) 捕获分组 (ab)+ 匹配"ab", "abab", "ababab"
(?:pattern) 非捕获分组 (?:ab)+ 匹配但不捕获内容
pattern1|pattern2 或操作 cat|dog 匹配"cat"或"dog"

2. 反向引用

语法 描述 示例 匹配结果
\1, \2, ... 引用第n个捕获组 (\w+)\s+\1 "hello hello", "test test"
\k<name> 命名分组引用 (?P<word>\w+)\s+\k<word> "hello hello"

3. 命名分组

语法 描述 示例
(?P<name>pattern) Python风格命名分组 (?P<year>\d{4})
(?<name>pattern) 现代风格命名分组 (?<year>\d{4})

🔧 零宽断言 (60% 使用场景)

语法 描述 示例 匹配结果
exp1(?=exp2) 正向先行断言:exp1后面是exp2 Windows(?=XP|7) "Windows"后跟"XP"或"7"
exp1(?!exp2) 负向先行断言:exp1后面不是exp2 Windows(?!XP|7) "Windows"后不跟"XP"或"7"
(?<=exp2)exp1 正向后行断言:exp1前面是exp2 (?<=\$)\d+ "$"后面的数字
(?<!exp2)exp1 负向后行断言:exp1前面不是exp2 (?<!\$)\d+ 非"$"后面的数字

💎 特殊字符转义 (100% 必须掌握)

特殊字符 转义形式 描述
. \. 匹配点号
* \* 匹配星号
+ \+ 匹配加号
? \? 匹配问号
` ` |
( \( 匹配左括号
) \) 匹配右括号
[ \[ 匹配左方括号
] \] 匹配右方括号
{ \{ 匹配左花括号
} \} 匹配右花括号
^ \^ 匹配脱字符
$ \$ 匹配美元符号
\ \\ 匹配反斜杠

🌐 非打印字符 (40% 使用场景)

语法 描述 等价形式
\n 换行符 \x0a, \cJ
\r 回车符 \x0d, \cM
\t 制表符 \x09, \cI
\f 换页符 \x0c, \cL
\v 垂直制表符 \x0b, \cK
\s 任意空白字符 [ \f\n\r\t\v]
\S 任意非空白字符 [^ \f\n\r\t\v]

🎯 实用模式示例

1. 常见验证模式

# 邮箱验证
email_pattern = r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}"

# 手机号验证(中国)
phone_pattern = r"1[3-9]\d{9}"

# 身份证验证
id_card_pattern = r"\d{17}[\dXx]"

# IP地址验证
ip_pattern = r"\b(?:\d{1,3}\.){3}\d{1,3}\b"

# URL验证
url_pattern = r"https?://[^\s/$.?#].[^\s]*"

2. 数据提取模式

# 提取价格
price_pattern = r"\$?(\d+(?:,\d{3})*(?:\.\d{2})?)"

# 提取日期
date_pattern = r"\d{4}[-/]\d{1,2}[-/]\d{1,2}"

# 提取时间
time_pattern = r"\d{1,2}:\d{2}(?::\d{2})?"

# 提取HTML标签内容
html_tag_pattern = r"<(\w+).*?>(.*?)</\1>"

3. 文本处理模式

# 匹配重复单词
duplicate_word_pattern = r"\b(\w+)\s+\1\b"

# 匹配空行
empty_line_pattern = r"^\s*$"

# 匹配行首行尾空白
trim_pattern = r"^\s+|\s+$"

# 匹配多行注释
comment_pattern = r"/\*[\s\S]*?\*/"

📈 学习优先级建议

第一阶段:核心基础 (必须掌握)

  • 字符类:., [], [^], \d, \w, \s
  • 量词:*, +, ?, {n}, {n,m}
  • 定位符:^, $, \b
  • 分组:(), |
  • 转义:\.

第二阶段:进阶技能 (建议掌握)

  • 非贪婪:*?, +?, ??
  • 非捕获:(?:)
  • 反向引用:\1, \2
  • 字符集范围:[a-z], [A-Z], [0-9]

第三阶段:高级特性 (按需学习)

  • 零宽断言:(?=), (?! ), (?<=), (?<! )
  • 命名分组:(?P<name>)
  • 条件匹配:(?(condition)true-pattern|false-pattern)
  • 递归模式:(?R)

🔍 字符集中特殊符号详解

关键原理

字符集 [] 内部是一个"安全区",大部分特殊符号都失去特殊含义,变成字面字符。

例外规则

只有少数符号在字符集内仍有特殊含义:

  • - : 用于定义字符范围(如a-z),但在末尾时是字面字符
  • ^ : 在开头时表示否定(如[^a-z]),其他位置是字面字符
  • ] : 结束字符集定义
  • \ : 转义字符仍然有效

实例分析:邮箱正则表达式

r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}"

字符集 [a-zA-Z0-9._%+-] 解析

  • a-z : 小写字母范围
  • A-Z : 大写字母范围
  • 0-9 : 数字范围
  • . : 字面点号(不是任意字符)
  • _ : 字面下划线
  • % : 字面百分号
  • + : 字面加号(不是量词)
  • - : 字面减号(不是范围符号,因为在末尾)

记忆口诀:"方括号内是天堂,特殊符号都变样,只有减号和脱号,还有反斜要记牢"

🛠️ Python最佳实践

1. 使用原始字符串

# ✅ 推荐
pattern = r"\d+"

# ❌ 不推荐
pattern = "\\d+"

2. 预编译模式

# ✅ 推荐:预编译
email_pattern = re.compile(r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}")

for email in email_list:
    if email_pattern.match(email):
        print("有效邮箱")

3. 使用详细注释

# ✅ 推荐:详细注释
complex_pattern = re.compile(r"""
    ^                       # 行开始
    (\d{4}-\d{2}-\d{2})     # 日期组
    \s+                     # 空白分隔
    (\w+)                   # 用户名组
    :\s+                    # 冒号和空白
    (ERROR|WARN|INFO)       # 日志级别组
    .*                      # 日志内容
    $                       # 行结束
""", re.VERBOSE | re.MULTILINE)

📚 性能优化建议

  1. 简单优先:使用简单的字符类而非复杂的组合
  2. 避免回溯:减少嵌套量词和可选分组
  3. 使用锚点^$ 可以大幅提升匹配速度
  4. 预编译:重复使用的模式应该预编译
  5. 非贪婪:在不确定匹配长度时使用非贪婪量词

最后更新:2025年12月