2017-08-14 45 views
0

我正在使用python将化学公式转换为元素的比例。Python:从非解释字符串中获取数字。使用正则表达式?

例如: 我有一个列表["Ti5Cu3", "TiCu2", "Ti2Cu3"]作为输入列表,并且想要将它转换为[5/(5+3), 1/(1+2), 2/(2+3)]

如何获得元素标记后面的数字?我认为re库可能会有用吗?以及如何使用它来解决我的问题?

我的解决办法是现在:

def formula2por(s):        
    if s == "Ti":  
     return 1 
    elseif s == "Cu": 
     return 0 
    else:          
     t = re.match(r'Ti(.*)Cu(.*)', s).groups() 
     # pdb.set_trace()      
     if t[0] is not '': 
      x = int(t[0]) 
     else: 
      x = 1  
     if t[1] is not '': 
      y = int(t[1])                   
     else:         
      y = 1        
     return round(x/(x+y), 4) 

不过,我认为这是杂乱而不是这个问题的一个Python的方式。

谢谢。

+0

有趣的问题,但你究竟是在将这些分子转换成什么?钛和铜的分子量不是5,3,2等。我问这是因为我不明白你的转换,因此不能为你的问题建议一个正则表达式。 –

+0

我想你的第一个任务是在每个大写字母前分割字符串。 –

+0

你的字符串是什么格式?你只有2元素分子吗?你可以有C2H10O6吗?你想要结果是数字还是字符串?例如,字符串“1 /(1 + 2)”表示一个等于1/2的计算(你想要数字还是字符串?) – Thanassis

回答

3

您可以使用Ti(\d*)Cu(\d*)来捕捉数字和匹配的对象传递给更换功能;其中数字可以分别作为第一和第二捕获组访问:

lst = ["Ti5Cu3", "TiCu2", "Ti2Cu3"] 
​ 
def div_sub(match): 
    x, y = match.group(1), match.group(2) 
    x = 1 if x == '' else int(x) 
    y = 1 if y == '' else int(y) 
    return str(x/(x+y)) 
​ 
import re 
[float(re.sub(r"Ti(\d*)Cu(\d*)", div_sub, s)) for s in lst] 
# [0.625, 0.3333333333333333, 0.4] 
+0

这比我的更好。但是,如果输入包含“Ti”和“Cu”?通过添加更多if else子句?或者有更好的方法修改正则表达式模式?谢谢。 –

+0

你能举出一些不适合'Ti [0-9] Cu [0-9]'的示例输入吗?您可能仍然能够根据您的需要使用正则表达式模式。 – Psidom

0

您可以轻松地处理这个,如果我们让你有没有这三个字母代码的假设。然后,

def calculate(match): 
    i = 1, tmp = [] 
    while match.group(i) != '': 
     if match.group(i+1) == '': 
      tmp.append(1.0) 
     else: 
      tmp.append(float(match.group(i+1))) 
     i += 2 
    if i == 1: 
     return 0 
    else: 
     return tmp[0]/sum(tmp) 


import re 
required_list = [] 
pattern = re.compile("^([A-Z][a-z]?)(\d*\.?\d*)([A-Z][a-z]?)(\d*\.?\d*)") 
for compound in lst: 
    required_list.append(calculate(pattern.match(compound))) 

正如你可以看到,这个代码可以容易地适用于象高锰酸钾多元素的化合物并处理浮点指数。

相关问题