Python 提供了两种主要的方式使用正则表达式来分割字符串:

re.split()函数:这是最直接、最常用的方法,它直接返回一个分割后的列表。re.findall()或re.finditer()方法:这是一种更灵活、更强大的方法,可以让你在分割的同时捕获分隔符本身。
re.split() 函数
这是正则表达式分割的“标准”方法,它的行为类似于字符串的 split() 方法,但功能强大得多。
基本语法
import re re.split(pattern, string, maxsplit=0, flags=0)
pattern: 一个正则表达式字符串,用来匹配分隔符。string: 要分割的原始字符串。maxsplit(可选): 最大分割次数,如果指定了maxsplit,则最多进行maxsplit次分割,列表的长度最多为maxsplit + 1,默认为 0,表示分割所有可能的匹配项。flags(可选): 正则表达式标志,如re.IGNORECASE。
示例
示例 1:按一个或多个空格分割
字符串的 split() 方法默认只按单个空格分割,而 re.split() 可以轻松处理连续的空格。
import re text = "Python is a great language" # 使用 \s+ 匹配一个或多个空白字符(空格、制表符、换行符等) result = re.split(r'\s+', text) print(result) # 输出: ['Python', 'is', 'a', 'great', 'language']
示例 2:按特定字符或模式分割

假设我们想用逗号、分号或竖线来分割一个字符串。
import re data = "apple,banana;orange|grape" # 使用字符集 [;,|] 来匹配任意一个分隔符 result = re.split(r'[;,|]', data) print(result) # 输出: ['apple', 'banana', 'orange', 'grape']
示例 3:使用 maxsplit 限制分割次数
import re text = "one,two,three,four,five" result = re.split(r',', text, maxsplit=2) print(result) # 输出: ['one', 'two', 'three,four,five']
re.split() 的一个重要特性:捕获组
如果正则表达式模式中包含捕获组(即用圆括号 括起来的部分),那么匹配到的分隔符本身也会被包含在返回的列表中。
示例 4:捕获分隔符

假设我们想按空格分割,但同时又想知道每个空格在哪里。
import re text = "Python is fun" # 模式 r'(\s+)' 中的括号 () 形成了一个捕获组 result = re.split(r'(\s+)', text) print(result) # 输出: ['Python', ' ', 'is', ' ', 'fun']
再看一个更复杂的例子,按 或 分割,并保留分隔符。
import re text = "key1:value1;key2=value2" # 分隔符是 : 或 ;,用 ([:;]) 捕获 result = re.split(r'([:;])', text) print(result) # 输出: ['key1', ':', 'value1', ';', 'key2=value2']
re.findall() 或 re.finditer() 方法
这种方法更灵活,因为它允许你定义一个模式,这个模式既可以匹配“内容”,也可以匹配“分隔符”,通过仔细设计模式,你可以完全控制分割结果。
这种方法的核心思想是:将字符串想象成一个由“分隔符”和“内容”交替组成的序列,我们用一个正则表达式同时匹配这两部分,然后将“内容”部分提取出来。
基本思路
- 构建一个正则表达式,这个表达式能匹配任意一个“内容”或一个“分隔符”。
- 使用
re.findall()来查找所有匹配项。 - 结果列表会交替包含“内容”和“分隔符”。
- 通过索引(取偶数位或奇数位)来筛选出你想要的“内容”部分。
示例
示例 5:按单词边界分割
假设我们想按非单词字符(如 , , )来分割,并且不希望这些分隔符出现在结果中。
import re
text = "apple@banana#cherry$date"
# 模式解释:
# [\w]+: 匹配一个或多个单词字符(内容)
# |: 或者
# [@#$]: 匹配 @, #, $ 中的一个(分隔符)
# re.findall 会返回所有匹配到的模式,交替出现
result = re.findall(r'[\w]+|[@#$]', text)
print("Findall 的原始结果:", result)
# 输出: Findall 的原始结果: ['apple', '@', 'banana', '#', 'cherry', '$', 'date']
# 现在我们只保留“内容”部分(即偶数索引的元素)
split_result = result[::2] # 从头到尾,每隔一个取一个
print("最终分割结果:", split_result)
# 输出: 最终分割结果: ['apple', 'banana', 'cherry', 'date']
示例 6:更复杂的分割(同时保留分隔符)
如果我们不仅想要内容,还想保留分隔符,并且希望它们是成对出现的,这种方法就非常有用。
import re
text = "name:John;age:30;city:New York"
# 匹配 "内容:分隔符" 或 "内容;分隔符" 的组合
# 这个模式会匹配 "name:", "John;", "age:", "30;", "city:", "New York"
# 但我们只想匹配 "name:" 和 "age:" 这样的键值对分隔符
# 更好的方法是匹配 "key:value" 对
# 使用 finditer 可以获取更详细的信息
matches = re.finditer(r'([^:;]+):([^:;]+)', text)
result = []
for match in matches:
key = match.group(1)
value = match.group(2)
result.append(key)
result.append(value)
print(result)
# 输出: ['name', 'John', 'age', '30', 'city', 'New York']
总结与对比
| 特性 | re.split() |
re.findall() / re.finditer() |
|---|---|---|
| 核心功能 | 专门用于分割字符串。 | 通用模式匹配,可用于分割。 |
| 语法 | re.split(pattern, string) |
re.findall(pattern, string) |
| 结果 | 返回一个列表,默认只包含分割后的内容。 | 返回一个列表,包含所有匹配到的模式(内容、分隔符交替)。 |
| 捕获组 | 会将匹配到的分隔符(如果模式中有捕获组)包含在结果列表中。 | 模式设计决定了结果中包含什么。 |
| 灵活性 | 简单直接,适用于大多数分割场景。 | 极高,可以精确控制哪些部分是“内容”,哪些是“分隔符”,实现非常复杂的分割逻辑。 |
| 性能 | 对于简单分割,通常非常高效。 | 可能需要额外的步骤(如切片)来处理结果,但对于复杂逻辑更清晰。 |
| 推荐场景 | - 简单的模式匹配(如 \s+, [,;])。- 只需要分割后的内容,不需要分隔符。 |
- 需要同时获取内容和分隔符。 - 分割逻辑非常复杂,无法用单一 split 模式表达。- 需要对匹配到的每个部分进行单独处理。 |
何时使用哪个?
-
使用
re.split()当:- 你想快速、简单地按一个正则表达式模式分割字符串。
- 你只关心分割后的,不关心分隔符本身。
- 这是你的首选,因为它最符合“分割”这个操作的直觉。
-
使用
re.findall()/re.finditer()当:- 你不仅需要分割后的内容,还需要捕获分隔符。
- 你的分割逻辑非常复杂,分隔符本身可能包含多种情况,并且你需要分别处理。
- 你想从字符串中提取多个不同类型的交替模式。
re.split() 是分割的利器,而 re.findall() 则是模式匹配的瑞士军刀,后者可以通过巧妙的设计来完成前者的工作,并提供更多的控制力。
