第9集:正则表达式入门(上)

学习目标

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

  • 理解为什么需要正则表达式
  • 使用基本字符匹配
  • 使用常见的量词
  • 写简单的正则表达式匹配数字
  • 完成简单示例

9.1 为什么需要正则表达式?

正则表达式(Regular Expression,简称 regex 或 RE)是一种强大的文本模式匹配工具。

问题场景

假设你需要:

场景1:验证邮箱

用户输入:
"alice@example.com" ✓
"bob.example.com" ✗
"charlie@" ✗

你需要判断:这是不是一个有效的邮箱?

场景2:提取电话号码

文本:
"我的电话是13812345678,
另一个是13987654321"

你需要:
把这两个电话号码找出来!

场景3:替换文本

原文本:
"2024-02-19,
2023-12-31"

你需要:
把所有日期改成
"02/19/2024 这样的格式

没有正则表达式,这些任务会很繁琐!

正则表达式就是解决这类问题的神器!

9.2 基本字符匹配

让我们从最基本的开始。

精确匹配

最简单的正则表达式就是普通字符。

正则:hello

能匹配:
"hello" ✓
"Hello" ✗(大小写敏感)
"helloworld" ✗(多了字符)
"hell" ✗(少了字符)

点号(.):匹配任意单个字符

正则:h.llo

能匹配:
"hello" ✓
"hallo" ✓
"h1llo" ✓
"h llo" ✓
"hxxllo" ✗(点号只匹配一个字符)

字符类([ ]):匹配方括号内的任意一个字符

正则:h[ae]llo

能匹配:
"hello" ✓
"hallo" ✓
"hillo" ✗(i 不在 [ae] 里)

范围:[a-z] 匹配所有小写字母

正则:[a-z]
匹配:a, b, c, ..., z

正则:[0-9]
匹配:0, 1, 2, ..., 9

正则:[a-zA-Z0-9]
匹配:所有字母和数字

否定字符类([^ ]):不匹配方括号内的字符

正则:h[^ae]llo

能匹配:
"hillo" ✓
"h1llo" ✓
"hello" ✗(e 在 [^ae] 里,所以不匹配)

9.3 量词

量词指定前面的字符可以出现多少次。

星号(*):出现 0 次或多次

正则:ab*c

能匹配:
"ac" ✓(b 出现 0 次)
"abc" ✓(b 出现 1 次)
"abbc" ✓(b 出现 2 次)
"abbbbbc" ✓(b 出现 5 次)

加号(+):出现 1 次或多次

正则:ab+c

能匹配:
"ac" ✗(b 必须至少出现 1 次)
"abc" ✓(b 出现 1 次)
"abbc" ✓(b 出现 2 次)

问号(?):出现 0 次或 1 次

正则:ab?c

能匹配:
"ac" ✓(b 出现 0 次)
"abc" ✓(b 出现 1 次)
"abbc" ✗(b 出现 2 次,太多了)

大括号({n}):精确出现 n 次

正则:ab{3}c

能匹配:
"abbbc" ✓(b 出现 3 次)
"abc" ✗(b 只出现 1 次)
"abbbbc" ✗(b 出现 4 次)

大括号范围:{n,}:至少出现 n 次

正则:ab{2,}c

能匹配:
"abbc" ✓
"abbbc" ✓
"abbbbbc" ✓
"abc" ✗(b 只出现 1 次)

大括号范围:{n,m}:出现 n 到 m 次

正则:ab{2,4}c

能匹配:
"abbc" ✓(2 次)
"abbbc" ✓(3 次)
"abbbbc" ✓(4 次)
"abbbbbc" ✗(5 次,太多了)

9.4 简单示例练习

练习1:匹配数字

目标:匹配一个数字

正则:[0-9]

能匹配:
"5" ✓
"a" ✗
"123" ✗(只匹配单个数字)

练习2:匹配多个数字

目标:匹配一个或多个数字

正则:[0-9]+

能匹配:
"1" ✓
"123" ✓
"12345" ✓
"a123" ✗(开头不是数字)

练习3:匹配以 h 开头,o 结尾

目标:h 开头,o 结尾,中间可以是任意字符

正则:h.*o

能匹配:
"hello" ✓
"hallo" ✓
"ho" ✓
"hello world" ✓
"h123o" ✓
"hell" ✗(不是 o 结尾)

练习4:匹配整数

目标:匹配整数(可以是正的,也可以是负的)

正则:-?[0-9]+

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

9.5 在 Python 中使用正则表达式

让我们用 Python 试试!

import re

# 检查匹配
pattern = r"hello"
text = "hello world"
match = re.search(pattern, text)
if match:
    print("找到了!")
else:
    print("没找到")

# 查找所有数字
pattern = r"[0-9]+"
text = "我有123个苹果,456个橘子"
numbers = re.findall(pattern, text)
print(numbers)  # ['123', '456']

9.6 自测一下

问题 1

正则表达式 a.*b 能匹配以下哪个?
A) "ab"
B) "a123b"
C) "axyb"
D) 以上都可以

问题 2

正则表达式 [0-9]{3} 能匹配?
A) "12"
B) "123"
C) "1234"
D) "a123"

问题 3

量词 + 表示什么?
A) 出现 0 次或多次
B) 出现 1 次或多次
C) 出现 0 次或 1 次
D) 精确出现 1 次


答案

  1. D
  2. B
  3. B

9.7 下集预告

下一集,我们继续学习:正则表达式入门(下)

我们会学习:

  • 字符类简写:\d, \w, \s
  • 分组与捕获
  • 锚点:^, $
  • 实战:识别数字、标识符
  • 更多有趣的例子

准备好了吗?我们下集见!


参考资料

  • Python re 模块文档
  • regex101.com(在线测试正则表达式的好网站)
  • 《精通正则表达式》
« 上一篇 抽象思维训练——程序员的基本功 下一篇 » 正则表达式入门(下)