第10集:正则表达式入门(下)

学习目标

通过本集的学习,你将能够:

  • 使用字符类简写:\d, \w, \s
  • 使用分组与捕获
  • 使用锚点:^, $
  • 实战识别数字和标识符
  • 完成更复杂的正则表达式

10.1 字符类简写

有些字符类很常用,正则表达式给它们提供了简写。

\d:数字(digit)

\d 相当于 [0-9]

正则:\d+
能匹配:
"123" ✓
"456" ✓
"abc" ✗

\w:单词字符(word)

\w 相当于 [a-zA-Z0-9_]
(字母、数字、下划线)

正则:\w+
能匹配:
"hello" ✓
"hello123" ✓
"hello_world" ✓
"hello-world" ✗(- 不在 \w 里)

\s:空白字符(space)

\s 匹配空白字符:
- 空格
- 制表符 (\t)
- 换行符 (\n)
- 回车符 (\r)

正则:hello\s+world
能匹配:
"hello world" ✓
"hello   world" ✓(多个空格)
"hello\tworld" ✓(制表符)
"helloworld" ✗(没有空格)

否定版本:\D, \W, \S

\d 匹配数字       → \D 匹配非数字
\w 匹配单词字符   → \W 匹配非单词字符
\s 匹配空白       → \S 匹配非空白

例子:

正则:\D+
匹配:"abc", "!@#", 但不匹配"123"

10.2 分组与捕获

用圆括号 () 可以分组,并且可以"捕获"匹配的内容。

基本分组

正则:(ab)+

能匹配:
"ab" ✓
"abab" ✓
"ababab" ✓

捕获分组

分组匹配的内容可以被提取出来!

import re

text = "我的电话是13812345678"
pattern = r"(\d{3})(\d{4})(\d{4})"
match = re.search(pattern, text)

if match:
    print("完整匹配:", match.group(0))
    print("第1组:", match.group(1))
    print("第2组:", match.group(2))
    print("第3组:", match.group(3))

输出:
完整匹配: 13812345678
第1组: 138
第2组: 1234
第3组: 5678

例子:提取日期

文本:2024-02-19
正则:(\d{4})-(\d{2})-(\d{2})

捕获结果:
group 1: 2024 (年)
group 2: 02   (月)
group 3: 19   (日)

Python 代码:

text = "今天是2024-02-19"
pattern = r"(\d{4})-(\d{2})-(\d{2})"
match = re.search(pattern, text)
if match:
    year = match.group(1)
    month = match.group(2)
    day = match.group(3)
    print(f"{month}/{day}/{year}")  # 02/19/2024

非捕获分组

如果你只想分组,不想捕获,可以用 (?:...)

正则:(?:ab)+
(分组,但不捕获)

10.3 锚点

锚点匹配位置,而不是字符。

^:字符串开头

正则:^hello

能匹配:
"hello world" ✓(hello 在开头)
"say hello" ✗(hello 不在开头)

$:字符串结尾

正则:hello$

能匹配:
"say hello" ✓(hello 在结尾)
"hello world" ✗(hello 不在结尾)

同时用 ^ 和 $:精确匹配整个字符串

正则:^hello$

只能匹配:
"hello" ✓
"hello world" ✗
"say hello" ✗

例子:验证完整数字

目标:整个字符串都是数字

正则:^\d+$

能匹配:
"123" ✓
"4567" ✓
"123a" ✗(有字母)
"a123" ✗(有字母)

10.4 实战:识别数字和标识符

让我们来实战一下!

任务1:识别整数

目标:识别整数

正则:^-?\d+$

能匹配:
"123" ✓
"-456" ✓
"0" ✓
"+789" ✗(我们没处理加号)
"12.3" ✗(有小数点)

任务2:识别浮点数

目标:识别浮点数

分析:
- 可以有小数点
- 小数点前后至少一边有数字
- 可以有负号

正则:^-?(\d+\.\d*|\.\d+|\d+)$

解释:
\d+\.\d*  → 123.456, 123.
\.\d+     → .456
\d+       → 123 (整数也是浮点数的一种)

能匹配:
"123" ✓
"123.456" ✓
".456" ✓
"123." ✓
"-123.456" ✓

任务3:识别标识符

目标:识别编程语言的标识符

规则:
- 开头:字母或下划线
- 后面:字母、数字、下划线

正则:^[a-zA-Z_][a-zA-Z0-9_]*$

或用简写:
^[a-zA-Z_]\w*$

能匹配:
"hello" ✓
"_world" ✓
"hello123" ✓
"hello_world" ✓
"123hello" ✗(数字开头)
"hello-world" ✗(有减号)

10.5 更多例子

例子1:验证邮箱(简化版)

正则:^[\w.-]+@[\w.-]+\.\w+$

能匹配:
"alice@example.com" ✓
"bob.smith@example.co.uk" ✓
"charlie_123@test.org" ✓

例子2:验证手机号码(简化版)

假设:11位数字,1开头

正则:^1\d{10}$

能匹配:
"13812345678" ✓
"13987654321" ✓
"1234567890" ✗(不是11位)
"23812345678" ✗(不是1开头)

例子3:替换文本

目标:把日期从 yyyy-mm-dd 改成 mm/dd/yyyy

Python 代码:
import re

text = "2024-02-19, 2023-12-31"
pattern = r"(\d{4})-(\d{2})-(\d{2})"
result = re.sub(pattern, r"\2/\3/\1", text)
print(result)

输出:
02/19/2024, 12/31/2023

10.6 常用正则速查表

字符:
.     任意字符
[abc] a 或 b 或 c
[^abc]  不是 a/b/c 的字符
[a-z]  小写字母
[0-9]  数字

简写:
\d  数字 [0-9]
\w  单词字符 [a-zA-Z0-9_]
\s  空白字符
\D  非数字
\W  非单词字符
\S  非空白

量词:
*     0次或多次
+     1次或多次
?     0次或1次
{n}   恰好n次
{n,}  至少n次
{n,m} n到m次

锚点:
^  字符串开头
$  字符串结尾

分组:
(...)  捕获分组
(?:...) 非捕获分组

10.7 在 Python 中常用的 re 函数

import re

# 1. re.search:查找第一个匹配
match = re.search(pattern, text)
if match:
    print("找到了")

# 2. re.findall:查找所有匹配
results = re.findall(pattern, text)
print(results)

# 3. re.match:从开头匹配
match = re.match(pattern, text)

# 4. re.sub:替换
new_text = re.sub(pattern, replacement, text)

# 5. re.split:分割
parts = re.split(pattern, text)

10.8 自测一下

问题 1

\d 相当于什么?
A) [a-z]
B) [0-9]
C) [a-zA-Z0-9_]
D) 空白字符

问题 2

哪个正则能匹配"hello"并且只匹配"hello"?
A) hello
B) ^hello
C) hello$
D) ^hello$

问题 3

分组用什么括号?
A) [ ]
B) { }
C) ( )
D) < >


答案

  1. B
  2. D
  3. C

10.9 启蒙篇总结

🎉 恭喜!你已经完成了启蒙篇的学习!

我们学到了:

  1. 什么是编译器以及为什么需要它
  2. 计算机是如何执行程序的
  3. 编程语言的家族树
  4. 编译器的工作流程
  5. 历史上的编译器传奇
  6. 为什么要学习编译原理
  7. 如何搭建学习环境
  8. 抽象思维训练
  9. 正则表达式入门(上)
  10. 正则表达式入门(下)

你现在已经有了坚实的基础!

10.10 下一篇章预告

下一篇章,我们将进入:编程语言基础篇

我们会学习:

  • Python 快速入门(变量、数据类型、控制流)
  • Python 函数、类、文件操作
  • 理解编程语言的语法
  • 上下文无关文法
  • BNF 表示法
  • 语言设计原则
  • 作用域与绑定
  • 类型系统
  • 以及更多...

准备好了吗?我们下一篇章见!


参考资料

  • Python re 模块官方文档
  • regex101.com(在线测试正则表达式)
  • 《精通正则表达式》
  • 各种正则表达式速查表
« 上一篇 正则表达式入门(上) 下一篇 » Python快速入门——变量与数据类型