杰瑞科技汇

Python正则split如何分割特定模式?

re.split() 是 Python re 模块中的一个强大函数,它允许你使用一个正则表达式作为分隔符来分割字符串,这比标准的字符串 split() 方法功能要强大得多,后者只能使用固定的字符串作为分隔符。

Python正则split如何分割特定模式?-图1
(图片来源网络,侵删)

基本语法

re.split(pattern, string, maxsplit=0, flags=0)

参数说明:

  • pattern: 一个正则表达式字符串,用来匹配分隔符。
  • string: 要被分割的原始字符串。
  • maxsplit (可选): 一个整数,表示最大分割次数,如果提供了 maxsplit,那么最多会发生 maxsplit 次分割,列表的长度将最多为 maxsplit + 1,默认为 0,表示分割所有匹配的地方。
  • flags (可选): 正则表达式标志,如 re.IGNORECASEre.MULTILINE 等,用于修改正则表达式的匹配行为。

返回值:

返回一个列表,包含分割后的子字符串。


简单示例

让我们从一个简单的例子开始,感受一下 re.split() 的用法。

Python正则split如何分割特定模式?-图2
(图片来源网络,侵删)

示例 1:按空格分割(类似 str.split()

import re
text = "hello world python"
# 按一个或多个空格分割
result = re.split(r'\s+', text)
print(result)
# 输出: ['hello', 'world', 'python']
text_with_multiple_spaces = "hello   world   python"
result = re.split(r'\s+', text_with_multiple_spaces)
print(result)
# 输出: ['hello', 'world', 'python']  # 自动处理了多个空格
  • r'\s+' 是一个正则表达式,\s 匹配任何空白字符(空格、制表符、换行符等), 表示“一个或多个”。

示例 2:使用 maxsplit 参数

import re
text = "apple,banana,orange,grape"
# 只分割前两次
result = re.split(r',', text, maxsplit=2)
print(result)
# 输出: ['apple', 'banana', 'orange,grape']

高级用法:捕获组与分隔符

这是 re.split() 一个非常重要且容易混淆的特性。

规则: 如果你的正则表达式模式中包含括号 (即捕获组),那么被匹配到的分隔符本身也会被包含在返回的列表中

示例 3:包含捕获组的分割

假设我们想用 或 来分割,并且我们想保留这些分隔符。

import re
text = "apple:banana,orange;grape"
# 模式 r'([,:;])' 会匹配 : 或 , 或 ;,并且将它们捕获
result = re.split(r'([,:;])', text)
print(result)
# 输出: ['apple', ':', 'banana', ',', 'orange', ';', 'grape']

分析:

Python正则split如何分割特定模式?-图3
(图片来源网络,侵删)
  1. 首先匹配到 apple 和 之间的 , 被捕获,列表变为 ['apple', ':']
  2. 然后匹配到 banana 和 之间的 , 被捕获,列表变为 ['apple', ':', 'banana', ',']
  3. 以此类推。

如何处理这种情况? 我们不希望分隔符混在结果里,一个常见的技巧是使用非捕获组

示例 4:使用非捕获组避免包含分隔符

import re
text = "apple:banana,orange;grape"
# (?:...) 是一个非捕获组,它只用于分组,但不捕获匹配的内容
result = re.split(r'([,:;])', text) # 错误的做法,会包含分隔符
print("错误的做法:", result)
# 正确的做法:使用非捕获组或者不使用分组
# 如果不需要捕获分隔符,直接写分隔符字符即可
result_correct = re.split(r'[:,;]', text)
print("正确的做法:", result_correct)
# 输出: ['apple', 'banana', 'orange', 'grape']

实用案例

案例 1:分割混合的数字和字母

import re
text = "abc123def45ghi678"
# 使用 (\d+) 来分割,并且捕获数字组
result = re.split(r'(\d+)', text)
print(result)
# 输出: ['abc', '123', 'def', '45', 'ghi', '678', '']
  • (\d+) 会匹配一个或多个数字,因为 是捕获组,'123', '45', '678' 被包含在结果列表中。
  • 最后有一个空字符串 ,因为字符串末尾有一个数字分割符,分割后后面没有内容了。

案例 2:分割句子,但保留标点符号

假设我们想按空格分割句子,但希望标点符号(如 , )和前面的单词连在一起。

import re
sentence = "Hello, world! This is a test."
# 我们想用 "空白字符 + 可选的标点" 作为分隔符
# 但又不希望把标点符号从单词上分开
# 一个巧妙的方法是:只匹配空白字符作为分割点
result = re.split(r'\s+', sentence)
print(result)
# 输出: ['Hello,', 'world!', 'This', 'is', 'a', 'test.']

这正好达到了我们的目标,如果我们的目标是分割单词和标点,我们可以这样做:

import re
sentence = "Hello, world! This is a test."
# 分割单词和标点
result = re.split(r'([,.!])', sentence)
# 去掉列表中的空字符串
final_result = [s for s in result if s]
print(final_result)
# 输出: ['Hello', ',', ' world', '!', ' This', ' is', ' a', ' test', '.', '']
# 再次清理一下,去掉空格
final_result_clean = [s.strip() for s in final_result if s.strip()]
print(final_result_clean)
# 输出: ['Hello', ',', 'world', '!', 'This', 'is', 'a', 'test', '.']

str.split() 的对比

特性 str.split(sep=None) re.split(pattern, string)
分隔符 只能是固定的字符串或 None(按任意空白分割)。 可以是任何复杂的正则表达式。
功能 功能有限。 功能极其强大,可以匹配模式、空白、字符集等。
捕获组 无此概念。 如果分隔符模式中有捕获组 ,匹配到的分隔符会包含在结果中。
性能 对于简单的固定分隔符,速度更快。 对于复杂模式非常强大,但通常比 str.split() 慢。
  • 如果你只是想用单个字符(如 或 )或空白字符分割字符串,优先使用 str.split(),因为它更简单、更高效。
  • 如果你的分隔符不是一个固定字符串,而是一个模式(一个或多个空格、特定字符集、单词边界等),re.split() 是不二之选。

希望这个详细的解释能帮助你完全掌握 Python 中的正则表达式分割!

分享:
扫描分享到社交APP
上一篇
下一篇