我正在尝试为一个应用程序编写一个方法,它接受一个像"CH3COOH“这样的化学公式,并返回某种充满符号的集合。
CH3COOH将返回C、H、C、O、O、H
我已经有了一些可以正常工作的东西,但是它非常复杂,并且使用了大量的代码和很多嵌套的if-else结构和循环。
有没有一种方法,我可以通过在String.split中使用某种正则表达式,或者在其他一些优秀的简单代码中实现这一点?
发布于 2010-09-19 02:45:25
我已经开发了几篇关于如何解析分子式的系列文章,包括更复杂的公式,如C6H2(NO2)3CH3。
最近的一次是我在PyCon2010上的演讲"PLY and PyParsing“,我使用一个分子式计算器作为我的样本问题来比较这两个Python解析系统。甚至还有一个video of my presentation。
该演示文稿基于我使用ANTLR语言开发的分子式解析器的three-part series of articles。在part 3中,我将ANTLR解决方案与手工编写的正则表达式解析器以及PLY和PyParsing中的解决方案进行了比较。
regexp和PLY解决方案最初是在two-part series中开发的,使用Python语言编写解析器的两种方式。
regexp解决方案和基本ANTLR/PLY/PyParsing解决方案使用A-Z?\d*这样的正则表达式来匹配公式中的项。这是@David M建议的。
这是用Python编写的
import re
# element_name is: capital letter followed by optional lower-case
# count is: empty string (so the count is 1), or a set of digits
element_pat = re.compile("([A-Z][a-z]?)(\d*)")
all_elements = []
for (element_name, count) in element_pat.findall("CH3COOH"):
if count == "":
count = 1
else:
count = int(count)
all_elements.extend([element_name] * count)
print all_elements当我运行这段代码(使用醋酸是硬编码的,CH3COOH)时,我得到
['C', 'H', 'H', 'H', 'C', 'O', 'O', 'H']请注意,这一小段代码假定分子式是正确的。如果你给它一些像"##$%^O2#$$#“这样的东西,那么它将忽略它不知道的字段,并给出'O','O‘。如果你不想这样做,那么你必须让它更健壮一点。
如果您想支持更复杂的公式,比如C6H2(NO2)3CH3,那么您需要了解一些树数据结构,特别是(正如@Roman指出的)抽象语法树(通常称为ASTs)。这太复杂了,无法进入这里,所以请参阅我的演讲和文章以了解更多细节。
发布于 2010-06-04 21:27:17
如果您只需要处理简单的情况,则使用正则表达式的解决方案是最好的方法。否则,您需要构建像Abstract Syntax Tree这样的东西并对其进行评估,或者使用Polish Notation。
例如,TNT公式C6H2(NO2)3CH3应如下所示:
(+ (* C 6) (* H 2) (* (+ N (* O 2)) 3) C (+ H 3))发布于 2010-06-04 22:21:55
你有没有考虑过用Chemical Markup Language来表达你的化学公式?它非常多才多艺,有很多工具/查看器可以在2D到3D中呈现这些化学聚集或化合物。
https://stackoverflow.com/questions/2974362
复制相似问题