我使用此代码在\.*[\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']
请查看我的预期结果,以便了解我正在努力实现的目标。
答案 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
内部并不特殊,所以你需要使用(非捕获)分组交替。