杰瑞科技汇

Python findall 如何匹配中文?

re.findall() 是 Python re (正则表达式) 模块中的一个核心函数,用于在字符串中查找所有匹配正则表达式的子串,并以列表的形式返回它们,处理中文的关键在于如何正确地写出匹配中文字符的正则表达式

Python findall 如何匹配中文?-图1
(图片来源网络,侵删)

核心问题:如何匹配中文字符?

在正则表达式中,中文字符通常属于 Unicode 字符集,最直接和常用的方法是使用 Unicode 属性来匹配汉字。

使用 \p{Han} (推荐,但需 regex 库)

\p{Han} 是一个 Unicode 属性,专门匹配所有汉字(包括简体中文和繁体中文),这是最标准、最准确的方法。

注意: Python 内置的 re 模块不完全支持 \p{...} 语法,你需要安装并使用第三方库 regex,它是 re 的超集,功能更强大,完全支持 Unicode 属性。

安装 regex 库:

Python findall 如何匹配中文?-图2
(图片来源网络,侵删)
pip install regex

使用示例:

import regex # 注意,我们导入的是 regex 而不是 re
text = "你好,世界!Hello World! 这是一个测试 123。"
# 使用 \p{Han} 匹配所有中文字符
chinese_list = regex.findall(r'\p{Han}', text)
print(chinese_list)
# 输出: ['你', '好', '世', '界', '这', '是', '一', '个', '测', '试', '中']

\p{Han} 会精确匹配任何一个汉字,所以结果是一个单个字符的列表,如果你想匹配连续的汉字词语,可以加上 量词。

import regex
text = "你好,世界!这是一个关于Python和中文的测试。"
# 使用 \p{Han}+ 匹配一个或多个连续的汉字
chinese_words_list = regex.findall(r'\p{Han}+', text)
print(chinese_words_list)
# 输出: ['你好', '世界', '这是一个', '#39;, '中文', '的', '测试']

使用 Unicode 范围 (通用,适用于 reregex)

如果你不想安装第三方库,或者只需要匹配常见的简体中文,可以使用 Unicode 编码范围来构建字符集。

  • 基本汉字范围: \u4e00\u9fff
  • 扩展A区: \u3400\u4dbf
  • 扩展B-F区: 包含更多生僻字

一个常见的做法是匹配基本汉字范围。

Python findall 如何匹配中文?-图3
(图片来源网络,侵删)

使用 re 模块的示例:

import re
text = "你好,世界!Hello World! 这是一个测试 123。"
# 使用 [\u4e00-\u9fff] 匹配一个基本中文字符
# 注意:这里需要写成字符集 [...] 的形式
chinese_list = re.findall(r'[\u4e00-\u9fff]', text)
print(chinese_list)
# 输出: ['你', '好', '世', '界', '这', '是', '一', '个', '测', '试', '中']
# 匹配连续的汉字词语
chinese_words_list = re.findall(r'[\u4e00-\u9fff]+', text)
print(chinese_words_list)
# 输出: ['你好', '世界', '这是一个', '测试', '中']

更全面的范围(推荐): 为了覆盖更多汉字,可以组合多个范围。

import re
text = "𠮷𠮷𠮷 你好,世界!" # 包含一个扩展B区的字符
# 匹配基本汉字、扩展A区、扩展B区
# 注意:扩展B区的字符是代理对(surrogate pair),在re模块中处理可能会有问题
# 更稳健的方式是使用regex库的\p{Han}
pattern = r'[\u4e00-\u9fff\u3400-\u4dbf\U00020000-\U0002a6df]+'
# 在 re 模块中,\U00020000 可能无法正确匹配所有扩展字符
# 所以对于生僻字,regex 库是更好的选择
chinese_words_list = re.findall(pattern, text)
print(chinese_words_list)
# 输出: ['你好', '世界'] # 注意开头的 "𠮷𠮷𠮷" 可能没有被正确匹配

实战应用场景

场景1:从混合文本中提取所有中文句子

假设你想从一个包含中文、英文和标点符号的段落中,提取出所有完整的中文句子。

import re
mixed_text = """
Python 是一种解释型、高级和通用的编程语言。
由吉多·范罗苏姆创造,于1991年首次发布。
它支持多种编程范式,包括结构化、过程式、面向对象和函数式编程。
The language's design philosophy emphasizes code readability with its notable use of significant whitespace.
"""
# 思路:匹配一个或多个汉字,后面跟着一个句号、问号或感叹号
# 中文句子通常以这些标点结尾
# [\u4e00-\u9fff] 匹配汉字,[。!?] 匹配中文标点
chinese_sentences = re.findall(r'[\u4e00-\u9fff]+[。!?]', mixed_text)
for sentence in chinese_sentences:
    print(sentence)

输出:

Python 是一种解释型、高级和通用的编程语言
由吉多·范罗苏姆创造,于1991年首次发布
它支持多种编程范式,包括结构化、过程式、面向对象和函数式编程

(注意:这个例子中 "Python" 被误判,因为它后面跟着句号,在实际应用中,需要更复杂的逻辑来区分语言。)

场景2:提取字符串中的中文和数字

假设你想从一个文件名或路径中提取出中文部分和数字部分。

import re
filename = "产品报告_2025年_v2.5_最终版.xlsx"
# 匹配连续的中文或连续的数字
# | 表示 "或" (or)
# [\u4e00-\u9fff]+ 匹配一个或多个汉字
# \d+ 匹配一个或多个数字
parts = re.findall(r'[\u4e00-\u9fff]+|\d+', filename)
print(parts)
# 输出: ['产品报告', '2025', '最终版']

总结与建议

方法 优点 缺点 推荐场景
\p{Han} (使用 regex 库) 最标准、最准确,自动涵盖所有汉字(简、繁、生僻字),代码可读性高。 需要安装第三方库 regex 强烈推荐,任何需要处理中文的正则表达式场景,尤其是在处理可能包含生僻文的文本时。
[\u4e00-\u9fff] (使用 re 模块) 无需额外安装,Python 内置支持,能满足大部分常见简体文本需求。 范围有限,不包含繁体和生僻字,写法稍显繁琐。 快速脚本、处理明确只包含基本汉字的文本、或者不允许安装第三方库的环境。

最佳实践:

  1. 首选 regex 库和 \p{Han}:这是最稳健、最不容易出错的方案,能应对各种复杂的中文文本。
  2. 次选 re 模块和 Unicode 范围:如果项目限制不能安装第三方库,或者你明确知道文本中只包含基本汉字,这是一个可行的方案。
  3. *结合 或 `量词**:根据你的需求,使用+(一个或多个) 或*` (零个或多个) 来匹配单个字符或连续的词语。
  4. 注意字符集:在 re 模块中,匹配单个字符时,记得用方括号 [] 括起来,如 [\u4e00-\u9fff],而不是 \u4e00-\u9fff
分享:
扫描分享到社交APP
上一篇
下一篇