首页 > 解决方案 > Python由多个特定字符拆分字符串并保留“分隔符”

问题描述

我有一个这样的化合物列表:

ex = ['CrO3', 'Cr8O21', 'NbCrO4']

我想分别获取元素和数字。像这样的东西:

['Cr','O',3]

['Cr',8,'O',21]

['Nb','Cr','O',4]

然而,这必须是一个通用过程——这些并不总是我正在使用的化合物。我认为这可以使用正则表达式和 split() 函数来完成。但是,我很难找到正确的正则表达式来得到我想要的。

这是我现在所拥有的:

# elements to split by
split_elements = ['Cr','Nb','O']

def split(compound, split_elements):
    separated = []
    splitstr = ")|(?=".join([str(elem) for elem in split_elements]) 
    splitstr = '('+splitstr+')'
    # splitstr will end up like this: 
    # (Cr)|(?=Nb)|(?=O)

    result = list(filter(None,re.split(splitstr, compound)))
    separated.append(result)

    return(separated)

for item in ex:
    print(split(item, split_elements))
# Output
# [['Cr', 'O3']]
# [['Cr', '8O21']]
# [['Nb', 'Cr', 'O4']]

正如你所看到的,这些数字仍然是附加的,我不知道为什么。我已经搜索了一个类似的问题,但我找不到任何问题(我现在所拥有的已经是疯狂谷歌搜索的结果)。

有没有人有任何解决方案或建议?

标签: pythonregexsplit

解决方案


可以re.findall用来分解化合物。

>>> import re    
>>> ex = ['CrO3', 'Cr8O21', 'NbCrO4']
>>> re.findall('[A-Z][a-z]?|\d*', ex[0])
['Cr', 'O', '3']
>>> re.findall('[A-Z][a-z]*|\d+', ex[1])
['Cr', '8', 'O', '21']
>>> re.findall('[A-Z][a-z]*|\d+', ex[2])
['Nb', 'Cr', 'O', '4']

尽管如果您打算做任何更复杂的事情,您可能应该查看 PyPI 上处理化学的众多软件包之一。


推荐阅读