正则表达式与文本处理 (re)
需要严格区分的是:re 是一个模块,包含了一系列执行正则操作的函数(如 re.sub、re.search);而部分函数会返回一个 re.Match - 类的实例对象,我们需要调用该实例的方法(如 .group())来获取最终数据。
一. 认识正则表达式与 re 模块
正则表达式 (Regular Expression,常简称为 regex 或 RE) 是一种专门用于处理字符串的强大工具。它允许你通过定义一套"规则暗号",在海量文本中快速进行查找、提取、替换等高级操作。
在 Python 中,正则表达式是内置标准库,无需安装即可直接导入:
python
import re
核心概念:你可以把普通的字符串查找(如 text.find("apple"))理解为"精确制导",而正则表达式则是"特征制导"。比如,它可以帮你一键匹配出"所有的11位手机号"、"所有包含@的邮箱地址",或是"清洗掉所有的标点符号"。
二. 前置知识:原始字符串前缀 ( r"..." )
在编写正则表达式时,我们极其频繁地使用反斜杠 \。为了避免 Python 自带的转义字符(如 \n 代表换行)与正则表达式的转义发生冲突,强烈建议在所有正则表达式的字符串前面加上字母 r (代表 raw string,原生字符串)。
示例:
python
# 普通字符串:Python会认为\n是换行符
s1 = "a\nb"
# 原生字符串:Python会原封不动地保留\和n两个字符,直接交给re模块解析
s2 = r"a\nb"
三. 核心语法:正则表达式
正则表达式由普通字符(如字母 a-z)和具有特殊含义的"元字符"组成。以下是自然语言处理(NLP)和数据清洗中最常用的规则:
| 元字符/语法 | 含义说明 | 匹配示例 |
|---|---|---|
r"xx" |
普通字符(字面)匹配。精确查找完全相同的目标字符串。 | r"app" 只能精确提取出 "app" 这个完整的单词。 |
[abc] |
字符集合。匹配括号内的任意一个字符。 | [aeiou] 匹配任意一个元音字母。 |
[a-z] |
字符范围。匹配指定范围内的任意字符。 | [A-Za-z0-9] 匹配任意大小写字母或数字。 |
[^abc] |
反向字符集合。^ 在中括号内表示"非"。 |
[^A-Za-z0-9] 匹配除了字母和数字之外的所有字符 (如标点、空格)。 |
\d |
数字。等价于 [0-9]。 |
r"\d" 匹配单个数字。 |
\w |
单词字符。等价于[A-Za-z0-9_]含下划线。 |
r"\w" 匹配单个字母、数字或下划线。 |
\s |
空白字符。匹配空格、制表符、换行符等。 | r"\s" 匹配任意一片空白。 |
+ |
量词。匹配前面的字符出现1次或多次。 | r"\d+" 匹配一整个数字串(如 "123") |
* |
量词。匹配前面的字符出现0次或多次。 | r"a*" 匹配 "", "a", "aa" 等。 |
四. re模块核心方法
在深度学习的数据清洗(特别是 NLP 文本预处理)阶段,re.sub 和 re.findall 是出场率最高的两个函数。
1. re.sub - 文本替换与清洗
作用:在目标字符串中,根据正则表达式规则查找匹配项,并将它们全部替换为指定的新字符串。这是 NLP 分词前进行"去除特殊符号、去除 HTML 标签"的最核心方法!
python
re.sub(pattern, repl, string, count=0, flags=0)
参数:
- 匹配规则 (pattern): 正则表达式的规则(通常使用
r"..."格式的 str)。 - 替换内容 (repl): 想要替换成的新内容(str)。
- 目标文本 (string): 需要被处理的原始长文本(str)。
- 替换次数 (count): 可选参数,指定最多替换几次。默认
0表示替换所有匹配项(int)。
返回值:
- 成功: 返回替换完成后的全新字符串(str)。原字符串不受影响。
示例:
python
import re
raw_text = "I love Python!!! <br /> It is so cool. 12345"
# 1. 消除 HTML 标签:找到 "<br />" 并替换为空格
text_no_html = re.sub(r"<br />", " ", raw_text)
# "I love Python!!! It is so cool. 12345"
# 2. 消除特殊符号:找到所有【非字母、非数字】的字符,替换为空格
clean_text = re.sub(r"[^A-Za-z0-9]", " ", text_no_html)
# "I love Python It is so cool 12345"
2. re.findall - 提取所有符合规则的内容
作用:扫描整个字符串,提取出所有完全符合正则表达式规则的部分。
python
re.findall(pattern, string, flags=0)
参数:
- 匹配规则 (pattern): 正则表达式的规则(str)。
- 目标文本 (string): 被扫描的原始文本(str)。
返回值:
- 成功: 返回一个包含所有匹配项的列表(list[str])。如果没找到,返回空列表
[]。
示例:
python
import re
text = "我的电话是13812345678,他的电话是13987654321,请联系。"
# \d+ 意味着提取连续的一个或多个数字
phone_numbers = re.findall(r"\d+", text)
print(phone_numbers)
# 输出: ['13812345678', '13987654321']
3. re.search - 寻找第一个匹配项
作用:扫描整个字符串,只要找到第一个符合规则的部分,就立刻停止并返回。常用于判断一段文本中是否包含某种格式的内容。
python
re.search(pattern, string, flags=0)
参数:
- 匹配规则 (pattern): 正则表达式的规则(str)。
- 目标文本 (string): 被扫描的原始文本(str)。
返回值:
- 成功: 返回一个包含匹配信息的正则匹配对象(Match Object)。若未找到,返回
None。需要调用.group()方法才能从对象中提取真实的字符串文本。
示例:
python
import re
text = "Error: File not found at line 400. Check code 500."
# 寻找文本中出现的第一个连续数字串
match_obj = re.search(r"\d+", text)
if match_obj:
print(match_obj.group()) # 输出: 400 (找到了就立刻停下,不会去管后面的500)
else:
print("没有找到数字。")