为什么这个re.split()会将空格作为列表中的单独项返回?

时间:2018-01-24 02:06:29

标签: python regex split

我使用此代码在\.*[\s$]分割字符串,但将分割字符保留为列表中的项目:

import re

markup = r"\{caption Figure 1: Leaf shapes\} \image:leaf_shapes.tiff"
tokens = re.split(r'(\.*[\s$])', markup)

我希望它返回此列表:

['\\caption ', 'Figure 1: Leaf shapes', '\\} ', '\\image:leaf_shapes.tiff']

但我得到了这个:

['\\{caption', ' ', 'Figure', ' ', '1:', ' ', 'Leaf', ' ', 'shapes\\}',
 ' ', '\\image:leaf_shapes.tiff']

为什么空格会在列表中作为单独的项目返回?

修改

我应该逃避反斜杠,而不是期限,所以我把代码更改为:

markup = r"\{caption Figure 1: Leaf shapes\} \image:leaf_shapes.tiff"
tokens = re.split(r'(\\.*[\s$])', markup)

但现在我得到了这个结果:

['', '\\{caption Figure 1: Leaf shapes\\} ', '\\image:leaf_shapes.tiff']

请查看我的预期结果,以便了解我正在努力实现的目标。

1 个答案:

答案 0 :(得分:1)

要获得预期的输出,您需要使用非贪婪的匹配,更改:

re.split(r'(\\.*?[\s$])', markup)

为:

.*

原因是$将尽可能多地匹配字符串(只要它仍然可以匹配它周围的固定锚),并且因为你的固定锚非常简单(一个反斜杠,任何字符,然后是尾随空格或['', '\\{caption ', 'Figure 1: Leaf shapes', '\\} ', '\\image:leaf_shapes.tiff'] 字符),它将匹配从第一个反斜杠到最后的空白字符。

得到输出:

tokens = re.split(r'(\\.*?[\s$])', markup)
if tokens and not tokens[0]:
    tokens.pop(0)
if tokens and not tokens[-1]:
    tokens.pop()

这几乎是你想要的(除了前导空字符串,因为你的正则表达式在字符串的最开头匹配)。您可以根据需要手动将其弹出,例如删除前导和尾随空字符串:

$

注意:如果您的意图是匹配到字符串的空格或结尾,而不是空格或文字[\s$],则需要将(?:\s|$)更改为$;在一个字符类A ^ B ^ B内部并不特殊,所以你需要使用(非捕获)分组交替。