如何使用 re.split 分割字符串?
我刚开始接触正则表达式,想要处理一些特别格式的字符串。我的目标是把字符串分割成不同的部分。如果一个字母不在括号里,它就应该变成输出列表中的一个单独元素。而在括号里的字母则应该放在一起。
下面是一些例子:
我的字符串 => 想要的列表
"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']