Я не уверен, что у меня есть атомные веса правильно, но я думаю, это можно исправить.
Для меня было непросто попытаться выяснить случаи, подобные 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, это не должно иметь никакого значения.