使用re.split()时开头空字符串出现的判定因素及相关疑问
关于re.split不同模式下空字符串的问题解析
首先明确Python中re.split()的核心规则:
- 当正则模式匹配到字符串的开头位置时,分割结果的第一个元素会是空字符串(因为开头到第一个分隔符之间没有内容);
- 当模式匹配到字符串的结尾位置时,结果的最后一个元素会是空字符串;
- 只有当模式是零长度匹配(比如
(?<=a)这类断言)时,才不会产生这类开头/结尾的空字符串,但[ ]+、[ ,.?!]+这类模式都是匹配非空长度的内容,理论上都会在首尾匹配时生成空字符串。
接下来针对你提到的现象逐一分析:
1. 为什么re.split("[ ]+"," a b c ")得到["",'a','b','c',""]
这完全符合re.split()的默认行为:
- 开头的两个空格被
[ ]+匹配为分隔符,开头到第一个分隔符之间没有字符,所以生成第一个空字符串; - 单词之间的多个空格被匹配为分隔符,分割出中间的
'a'、'b'、'c'; - 结尾的两个空格被匹配为分隔符,最后一个单词到结尾之间没有字符,所以生成最后一个空字符串。
2. 你提到的[ ,.?!]+或[ ]+模式无空字符串的可能原因
你描述的现象和re.split()的默认行为不符,大概率是以下两种情况:
- 混淆了
re.split()和str.split():Python内置的str.split()默认会忽略首尾的空白字符,并且以任意数量的空白字符作为分隔符,比如" a b c ".split()会直接得到['a','b','c'],没有空字符串; - 额外处理了分割结果:比如用
filter(None, re.split(...))过滤掉了空字符串,或者手动移除了首尾的空元素。
如果严格执行re.split(r'[ ,.?!]+', " a b c "),实际运行结果依然是["",'a','b','c',""]——因为[ ,.?!]+只是把分隔符的范围扩大到包含逗号、句号等,但开头的空格依然会被匹配,所以还是会生成首尾空字符串。
3. 开头仅一个空格时无空字符串?这是误解
实际测试re.split("[ ]+"," a b c "),结果依然是["",'a','b','c',""],开头的单个空格还是会被[ ]+匹配为分隔符,第一个元素依然是空字符串。你可能是把这个情况和str.split()混淆了:" a b c ".split()确实不会生成空字符串。
4. 如何得到无空格的单词列表
如果你想用正则分割得到纯单词列表,不需要保留空字符串,有两种简单方法:
- 方法一:用
re.findall()直接匹配单词,比如re.findall(r'\w+', " a b c "),直接得到['a','b','c']; - 方法二:对
re.split()的结果过滤空字符串,比如[x for x in re.split(r'[ ]+', " a b c ") if x]。
内容的提问来源于stack exchange,提问作者Елена Тюрина
相关产品推荐
相关产品推荐

