Парсинг химической формулы

Я пытаюсь записать метод для приложения, которое берет химическую формулу как "CH3COOH" и возвращает своего рода набор, полный их символов.

CH3COOH возвратился бы [C, H, H, H, C, O, O, H]

У меня уже есть что-то, что является видом работы, но это очень сложно и использует много кода с большим количеством вложенных если еще структуры и циклы.

Существует ли способ, которым я могу сделать это при помощи некоторого регулярного выражения с String.split или возможно в некотором другом блестящем простом коде?

21
задан Mark Amery 7 March 2017 в 14:56
поделиться

4 ответа

Предполагая, что он правильно написан заглавными буквами, каждый символ в уравнении соответствует этому регулярному выражению:

[A-Z][a-z]*\d*

(Для людей с химическими недостатками символом элемента всегда является заглавная буква, за которой следует, необязательно, одна или две строчные буквы - например, Hg для ртути)

Вы можете записать символ элемента и номер в группах следующим образом:

([A-Z][a-z]*)(\d*)

Так что да, теоретически это может быть то, с чем могут помочь регулярные выражения. Если вы имеете дело с формулами типа C 6 H 2 (NO 2 ) 3 (CH 3 ) 3 тогда ваша работа, конечно, немного сложнее ...

24
ответ дан 29 November 2019 в 06:21
поделиться

Я работаю над программой, которая требует вычисления молярной массы химических формул, поэтому я создал решение, которое работает с различными формулами.

Например, "(CH3)16(Tc(H2O)3CO(BrFe3(ReCl)3(SO4)2)2)2MnO4" приведет к "16C 48H 2Tc 12H 6O 2C 2O 4Br 12Fe 12Re 12Cl 8S 32O Mn 4O" (это соединение выдумано, но оно работает!)

Этот код написан на C#, поэтому я его не выложил. Если вам интересно, я могу выложить его для вас. На самом деле я написал полный ответ, прежде чем заметил тег java.

В любом случае, он работает, по сути, рекурсивно группируя блоки атомов, объединенных скобками. Он не работает с такими коэффициентами, как 2Pb (но (Pb)2 или Pb2 работает) или заряженными соединениями, такими как OH-.

Ни в коем случае нельзя назвать его простым или элегантным. Мне нужно было рабочее решение, поэтому я знаю, что есть лучшие способы (я даже не пробовал регулярные выражения!). Но это работает с формулами, которые мне нужны, возможно, это подойдет и вам.

Вот несколько тестовых примеров, на которых я его проверил. Посмотрите на них и дайте мне знать, будет ли код на C# все еще полезен для вас. Формат (входные данные, ожидаемый выход)

        ("Pb ", " Pb"); 
        ("H ", " H"); 
        ("Pb2 ", " 2Pb"); 
        ("H2 ", " 2H");             
        ("3Pb2 ", " 6Pb");
        ("Pb2SO4", " 2Pb S 4O");                                     
        ("PbH2 ", " Pb 2H");            
        ("(PbH2)2 ", " 2Pb 4H");
        ("(CCC)2 ", " 2C 2C 2C");
        ("Pb(H2)2 ", " Pb 4H");            
        ("(Pb(H2)2)2 ", " 2Pb 8H"); 
        ("(Pb(H2)2)2NO3 ", " 2Pb 8H N 3O"); 
        ("(Ag(Pb(H2)2)2)2SO4 ", " 2Ag 4Pb 16H S 4O");             
        ("Pb(CH3(CH2)2CH3)2", " Pb 2C 6H 4C 8H 2C 6H"); 
        ("Na2(CH3(CH2)2CH3)2", " 2Na 2C 6H 4C 8H 2C 6H");
        ("Tc(H2O)3Fe3(SO4)2", " Tc 6H 3O 3Fe 2S 8O");
        ("Tc(H2O)3(Fe3(SO4)2)2", " Tc 6H 3O 6Fe 4S 16O");
        ("(Tc(H2O)3(Fe3(SO4)2)2)2", " 2Tc 12H 6O 12Fe 8S 32O");
        ("(Tc(H2O)3CO(Fe3(SO4)2)2)2", " 2Tc 12H 6O 2C 2O 12Fe 8S 32O");
        ("(Tc(H2O)3CO(BrFe3(ReCl)3(SO4)2)2)2MnO4", " 2Tc 12H 6O 2C 2O 4Br 12Fe 12Re 12Cl 8S 32O Mn 4O");
        ("(CH3)16(Tc(H2O)3CO(BrFe3(ReCl)3(SO4)2)2)2MnO4", " 16C 48H 2Tc 12H 6O 2C 2O 4Br 12Fe 12Re 12Cl 8S 32O Mn 4O"); 
2
ответ дан 29 November 2019 в 06:21
поделиться

Рассматривали ли вы возможность выразить ваши химические формулы на Химическом языке разметки? Он очень универсален, и существует множество инструментов/просмотровщиков, которые могут отображать эти химические формулы или соединения в 2D и 3D.

4
ответ дан 29 November 2019 в 06:21
поделиться

Решение с регулярными выражениями - лучший подход, если вам нужно обрабатывать только простые случаи. В противном случае вам нужно построить что-то вроде абстрактного синтаксического дерева и оценить его или использовать польскую нотацию .

Например, формула TNT C6H2 (NO2) 3CH3 должна быть представлена ​​как:

(+ (* C 6) (* H 2) (* (+ N (* O 2)) 3) C (+ H 3))
12
ответ дан 29 November 2019 в 06:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: