之前在文章Python数据类型之字符串中介绍了split
等分割字符串的方法,但是你会发现只能指定一个分隔符,那在Python下指定多个分隔符像AWK命令那样来分割字符串应该怎么做呢?
string
对象的 split()
方法只适应于非常简单的字符串分割情形, 它并不允许有多个分隔符或者是分隔符周围不确定的空格。当你需要更加灵活的切割字符串的时候,那就需要借助re.split()
方法了。
>>> info = "My host ip address is 10.0.1.10, hwaddress is 52:54:00:B7:7A:0A"
>>> import re
>>> re.split(r'[.,:\s]\s*', info)
['My', 'host', 'ip', 'address', 'is', '10', '0', '1', '10', 'hwaddress', 'is', '52', '54', '00', 'B7', '7A', '0A']
>>>
>>> info = "My host ip address is 10.0.1.10, hwaddress is 52:54:00:B7:7A:0A "
>>> re.split(r'[.,:\s]\s*', info)
['My', 'host', 'ip', 'address', 'is', '10', '0', '1', '10', 'hwaddress', 'is', '52', '54', '00', 'B7', '7A', '0A',
'']
>>> re.split(r'[.,:\s]\s*', info.strip())
['My', 'host', 'ip', 'address', 'is', '10', '0', '1', '10', 'hwaddress', 'is', '52', '54', '00', 'B7', '7A', '0A']
函数re.split()
非常实用,因为它允许你为字符串指定多个分隔符。 比如,在上面的例子中,分隔符可以是点,逗号,分号或者是空格,并且后面紧跟着任意个的空格。 只要这个模式被找到,那么匹配的分隔符两边的实体都会被当成是结果中的元素返回。 返回结果为一个字段列表,这个跟str.split()
返回值类型是一样的, 但是如果字符串两边有空格的话,需要先进行str.strip
操作,然后再进行re.split()
操作即可。
当你使用re.split()
函数时候,需要特别注意的是正则表达式中是否包含一个括号捕获分组。 如果使用了捕获分组,那么被匹配的文本也将出现在结果列表中。比如,观察一下这段代码运行后的结果:
>>> string = re.split(r'(;|,|\s)\s*', info)
>>> string
['My', ' ', 'host', ' ', 'ip', ' ', 'address', ' ', 'is', ' ', '10.0.1.10', ',', 'hwaddress', ' ', 'is', ' ', '52:5
4:00:B7:7A:0A', ' ', '']
获取分割字符在某些情况下也是有用的。 比如,你可能想保留分割字符串,用来在后面重新构造一个新的输出字符串:
>>> line = 'asdf fjdk; afed, fjek,asdf, foo'
>>> fields = re.split(r'(;|,|\s)\s*', line)
>>> fields
['asdf', ' ', 'fjdk', ';', 'afed', ',', 'fjek', ',', 'asdf', ',', 'foo']
>>> values = fields[::2]
>>> delimiters = fields[1::2] + ['']
>>> values
['asdf', 'fjdk', 'afed', 'fjek', 'asdf', 'foo']
>>> delimiters
[' ', ';', ',', ',', ',', '']
>>> # Reform the line using the same delimiters
>>> ''.join(v+d for v,d in zip(values, delimiters))
'asdf fjdk;afed,fjek,asdf,foo'
如果你不想保留分割字符串到结果列表中去,但仍然需要使用到括号来分组正则表达式的话, 确保你的分组是非捕获分组,形如(?:...)
, 比如:
>>> line = 'asdf fjdk; afed, fjek,asdf, foo'
>>> re.split(r'(?:,|;|\s)\s*', line)
['asdf', 'fjdk', 'afed', 'fjek', 'asdf', 'foo']