如何使用 re.split 分割字符串?

0 投票
2 回答
4714 浏览
提问于 2025-04-16 13:54

我刚开始接触正则表达式,想要处理一些特别格式的字符串。我的目标是把字符串分割成不同的部分。如果一个字母不在括号里,它就应该变成输出列表中的一个单独元素。而在括号里的字母则应该放在一起。

下面是一些例子:

我的字符串 => 想要的列表

  • "ab(hpl)x" => ['a', 'b', 'hpl', 'x']
  • "(pck)(kx)(sd)" => ['pck', 'kx', 'sd']
  • "(kx)kxx(kd)" => ['kx', 'k', 'x', 'x', 'kd']
  • "fghk" => ['f', 'g', 'h', 'k']

我想知道怎么用正则表达式和 re.split 来实现这个功能?提前谢谢你的帮助。

2 个回答

1

你需要用 findall 而不是 split。可以使用这个正则表达式:r'(?<=\()[a-z]+(?=\))|[a-z]',它能处理你所有的测试案例。

>>> test_cases = ["ab(hpl)x", "(pck)(kx)(sd)", "(kx)kxx(kd)", "fghk"]
>>> pat = re.compile(r'(?<=\()[a-z]+(?=\))|[a-z]')
>>> for test_case in test_cases:
...     print "%-13s  =>  %s" % (test_case, pat.findall(test_case))
...
ab(hpl)x       =>  ['a', 'b', 'hpl', 'x']
(pck)(kx)(sd)  =>  ['pck', 'kx', 'sd']
(kx)kxx(kd)    =>  ['kx', 'k', 'x', 'x', 'kd']
fghk           =>  ['f', 'g', 'h', 'k']

编辑:

如果你想匹配大小写字母、数字和下划线,可以把 [a-z] 替换成 \w。如果你的括号永远不会不平衡(比如 "abc(def"),那么可以去掉前面的断言 (?<=\()

5

这件事不能用 re.split 来完成,因为这需要在零长度的匹配上进行分割。

根据 http://docs.python.org/library/re.html#re.split 的说明:

请注意,split 永远不会在空的模式匹配上分割字符串。

这里有一个替代的方法:

re.findall(r'(\w+(?=\))|\w)', your_string)

还有一个例子:

>>> for s in ("ab(hpl)x", "(pck)(kx)(sd)", "(kx)kxx(kd)", "fghk"):
...     print s, " => ", re.findall(r'(\w+(?=\))|\w)', s)
... 
ab(hpl)x  =>  ['a', 'b', 'hpl', 'x']
(pck)(kx)(sd)  =>  ['pck', 'kx', 'sd']
(kx)kxx(kd)  =>  ['kx', 'k', 'x', 'x', 'kd']
fghk  =>  ['f', 'g', 'h', 'k']

撰写回答