【问题标题】:How to Find Character After some Specific String? [Chemistry Code]如何在某些特定字符串之后查找字符? [化学代码]
【发布时间】:2019-06-06 18:45:37
【问题描述】:

我正在尝试编写代码,在其中输入分子(为方便起见,仅使用包含 C、H、O、Cl 和 N 的分子)进行输入并获取分子量。

如果我输入C2H4,它应该会进行计算:

MW = mass_C * 2 + mass_H *4

我需要代码在数字前取字母,然后将它与“字符串”后面的数字相乘,直到它到达末尾。

所以基本上,我如何获得数字前的字母?

PS:我是编码新手 :) 所以很高兴看到书面代码,而不仅仅是解释来理解我应该用于 RE 的格式。

【问题讨论】:

标签: python regex


【解决方案1】:

这里有一些简单的代码可以满足你的需要:

import re                                                                      

atomic_weights = {                                                             
    'Cl': 35.446,                                                              
    'C': 12.0096,                                                              
    'O': 15.99903,                                                             
    'H': 1.00784,                                                              
}                                                                              

pattern = r"(?P<element>" + "|".join(atomic_weights.keys()) + ")(?P<count>\d*)" 
expression = re.compile(pattern)                                               

while True:                                                                    
    formula = input("formula: ")                                               
    weight = 0                                                                 
    for match in expression.finditer(formula):                                 
        element = match.group('element')                                          
        count = match.group('count')                                           
        if count.isdigit():                                                    
            count = int(count)                                                 
        else:                                                                  
            count = 1
        weight += atomic_weights[element] * count                          
    print(f"{formula} weighs {weight}")

我只关注正则表达式的使用:

  • 首先我们使用以下特殊字符编译一个模式:
    • | 匹配它之前或之后的所有内容
    • \d 匹配所有数字
  • 和以下限定符:
    • * 匹配零个或多个(我们不一定需要数字)
  • 和命名组:
    • (?P&lt;name&gt;) 命名任何匹配的内容,以便以后可以轻松地再次引用它

然后我们将公式与我们创建的正则表达式进行匹配,并遍历所有匹配项以找到相应的元素权重和乘数。

小提示:此方法将完全忽略不知道其权重的元素。这可能不是你想要的......

希望这会有所帮助!

【讨论】:

  • 谢谢,我不知道这里的一些语法,但我会搜索它:)
  • 我很乐意提供帮助 :-)
  • @selinoktay 正则表达式的“join”语法特别有用,因为它只允许您更改 atomic_weights 中的一行而无需更改其他内容。 'r' 表示原始字符串,对正则表达式很有用。回复:这段代码忽略了元素,似乎可以在没有太多麻烦的情况下修复。您可以设置一个 check_string=formula,然后在“for”循环中删除每个匹配组。如果还有一些东西,让程序说它没有捕捉到所有东西。我认为这对原始海报来说是一个很好的练习。
  • @aschultz 感谢您的解释,“r”有点困扰我,但我现在明白了。
【解决方案2】:

我不确定我的原子量是否正确,但我想这可以解决。

对我来说棘手的一点是试图找出像 CH3 这样简单的(字母)(数字)正则表达式不起作用的情况。

re.findall 在这里完成了繁重的工作。可能有更好的方法来解析 C2H4 字符串,我会对它感兴趣,但这有效。显然你可以清理东西并制作更整洁的功能等。

但是这里的正则表达式,我怀疑你最感兴趣的是:寻找一串字母,大写或小写,然后是一串数字。这被传递给 calc_weight,它将字符串分成字母和数字。如果有的话,这些字母会被发送到一个原子量。如果不是,则抛出错误。然后权重乘以数字。

import re
import sys

weight = { 'cl': 30, 'n': 8, 'o': 12, 'c': 6, 'h': 2 }

def calc_weight(my_str):
    elt = my_str[1].lower()
    if not re.search("[0-9]", my_str[0]): amt = 1
    else: amt = re.sub("^[a-zA-Z]+", "", my_str[0])
    if elt not in weight: sys.exit(elt + " is not a valid element.")
    return int(amt) * weight[elt]

my_string = "C2H4"

a = re.findall("((Cl|H|O|C|N)[0-9]*)", my_string)

my_weight = 0
for b in a:
    my_weight += calc_weight(b)

print("Weight of", my_string, "is", my_weight)

代码上的一句话:my_str[0] 和 my_str[1] 是 findall 元组的一部分,因为我有两对括号。第一个是整体字符串,第二个是元素。

希望这会有所帮助。请注意,您可能可以改进代码:为错误的字符串抛出更好的错误消息等。但我想至少允许大写,例如如果有人输入了 Mg 或 MG,那应该没什么区别。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2015-08-31
  • 1970-01-01
  • 1970-01-01
  • 2022-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-18
相关资源
最近更新 更多