我有一个字符串,由字符串和数字(整数或浮点数)的交替字符串组成,这些字符串具有任意长度,我希望将它分成几个部分,每个部分都有最大可能的大小,这样一部分就会由字符串或(表示a)字符串组成。
我不需要考虑特殊形式的数字,例如指数,十六进制等;只是简单的浮点或整数。
一些例子:
>>> split("")
()
>>> split("p")
('p',)
>>> split("2")
('2',)
>>> split("a2b3")
('a', '2', 'b', '3')
>>> split("a2.1b3")
('a', '2.1', 'b', '3')
>>> split("a.1b3")
('a', '.1', 'b', '3')
但是,以下调用应该引发一些错误:
>>> split(3)
>>> split("a0.10.2")
>>> split("ab.c")
我的第一次尝试是使用re.split
。但是,这种尝试很天真,如果我写这些字母,它就不会保存分隔符:
>>> re.split("[a-z]", "a.1b3")
['', '.1', '3']
我的第二次尝试是使用itertools.groupby
。问题在于它并不关心数字的形式,例如:
>>> islowalpha = labmda s: str.isalpha(s) and str.islower(s)
>>> [''.join(g) for _, g in itertools.groupby("a0.10.2b", islowalpha)] # should raise
['a', '0.10.2', 'b']
注意:我不关心输出的形式,只要它是可迭代的。
注意:我已阅读this,但我无法使解决方案适应我的问题。主要区别在于我只需要允许接受的数字,而不是简单的数字和点列表。
答案 0 :(得分:2)
import re
def split_gen(x):
for f, s in re.findall(r'([\d.]+)|([^\d.]+)', x):
if f:
float(f)
yield f
else:
yield s
def split(x):
'''
>>> split("")
()
>>> split("p")
('p',)
>>> split("2")
('2',)
>>> split("a2b3")
('a', '2', 'b', '3')
>>> split("a2.1b3")
('a', '2.1', 'b', '3')
>>> split("a.1b3")
('a', '.1', 'b', '3')
>>> split(3)
Traceback (most recent call last):
...
TypeError: expected string or buffer
>>> split("a0.10.2")
Traceback (most recent call last):
...
ValueError: could not convert string to float: '0.10.2'
>>> split("ab.c")
Traceback (most recent call last):
...
ValueError: could not convert string to float: '.'
'''
return tuple(split_gen(x))
if __name__ == '__main__':
import doctest
doctest.testmod()
答案 1 :(得分:1)
使用re.sub
和itertools.cycle
进行一些游戏:
def split(s):
res = []
def replace(matchobj):
res.append(matchobj.group(0))
return ''
letter = re.compile('^([a-z]+)')
number = re.compile('^(\.\d|\d+\.\d+|\d+)')
if letter.match(s):
c = itertools.cycle([letter, number])
else:
c = itertools.cycle([number, letter])
for op in c:
mods = op.sub(replace, s)
if len(s) == len(mods):
return
elif not mods:
return res
s = mods
基本思路 - 创建两个交替的re
模式,并尝试将输入字符串与它们匹配。
包含一些示例的演示:
>>> split("2")
['2']
>>> split("a2b3")
['a', '2', 'b', '3']
>>> split("a.1b3")
['a', '.1', 'b', '3']
>>> split("a0.10.2")
>>> split("ab.c")
答案 2 :(得分:0)
问题在于你的问题的前提是合情合理的。如何区分浮点数与任意字符串?有很多方法可以解释。例如,
0.10.2
这可能意味着0.1,0.2。或0,.10,.2
如果数字是多少呢?
27.6734.98?
您需要指定首先是什么类型的数字和格式。例如:每个数字只有小数点后的一位数。
答案 3 :(得分:-1)
import re
string = 'a.2b3c4.5d'
REG_STR = r'([a-zA-Z])|(\.\d+)|(\d+\.\d+)|(\d+)'
matches = [m.group() for m in re.finditer(REG_STR, string) if re.finditer(REG_STR, string)]