2.1 线性符号系统:SMILES 与 InChI 本节摘要:SMILES 是用一行 ASCII 字符表达分子结构的语言,InChI 是由标准算法从结构生成的分层标识符。本节解剖 SMILES 的语法要素与解析流程,讲清 InChI 与 InChIKey 的分层设计,并通过"咖啡因的五种写法归一成同一身份"的完整案例,建立"字符串多变、身份唯一"的编目直觉。 编目柜台的第一课:学会在字符串层登记分子。它承上——1.2 节历史里 SMILES 的诞生动机在此落地;启下——本节输出的字符串就是 2.2 节解析成图的原材料。全册后续代码,一半从这里开始。 从苯环开始:一行字符串的解剖 是苯。六个小写字母排成一圈,首尾用同一个数字闭合。把这一行读明白,SMILES 就通了,它的全部语法只有六类要素。
本节摘要:SMILES 是用一行 ASCII 字符表达分子结构的语言,InChI 是由标准算法从结构生成的分层标识符。本节解剖 SMILES 的语法要素与解析流程,讲清 InChI 与 InChIKey 的分层设计,并通过"咖啡因的五种写法归一成同一身份"的完整案例,建立"字符串多变、身份唯一"的编目直觉。
编目柜台的第一课:学会在字符串层登记分子。它承上——1.2 节历史里 SMILES 的诞生动机在此落地;启下——本节输出的字符串就是 2.2 节解析成图的原材料。全册后续代码,一半从这里开始。
c1ccccc1 是苯。六个小写字母排成一圈,首尾用同一个数字闭合。把这一行读明白,SMILES 就通了,它的全部语法只有六类要素。
原子。普通元素符号直接写:C、N、O。小写字母表示芳香原子(c、n、o),大写表示脂肪族。方括号包裹的原子携带精细信息:[NH4+] 是铵根,[nH] 是带氢的芳香氮,[C@@H] 里的立体标记后面细讲。键。单键默认省略,= 双键、# 三键、/ 与 \ 标记双键两侧的顺反几何。支链。圆括号包裹分支,CC(=O)O 读作"碳-碳(双键氧)-氧",乙酸写成 CC(=O)O。环闭合。开环处写数字、闭环处写同一个数字,C1CCCCC1 是环己烷;同一原子可以带两个环号,稠环就这么表达。芳香性。芳香环用小写字母书写(c1ccccc1),解析器会重新感知芳香性而不是盲信大小写。省略氢。碳的价态决定氢数,C 默认四个单键、氢自动补齐;只有价态异常时才需要方括号明写。
解析器读入字符串的过程值得画出来,因为 2.2 节的分子图就是它的产物。

两个最常见的翻车点都发生在这条流水线的下半段:把芳香氮写成 N 而不是 n,价态校验报错;给季碳旁边多写一个不存在的氢,解析器直接拒绝整条记录。解析报错不是麻烦,是第一道质检——它替你拦下了大量脏数据。
SMILES 由人写,同一个分子可以有无穷多种合法写法;InChI(国际化合物标识符)则由标准算法从结构生成,不依赖写法。生成时算法做了三件事:把互变异构、电荷等化学常识标准化(规范化层);给原子定出与输入顺序无关的规范编号(规范化编号);按层组织信息——分子式层、连接表层、氢层,每层以斜杠分隔。InChIKey 是它的定长压缩版:首段编码分子骨架,次段编码质子化等残留差异,末位是版本标志位。
三者的分工用一张表说清:
| 标识符 | 谁生成 | 是否唯一 | 最适场景 |
|---|---|---|---|
| SMILES | 人或程序,写法不唯一 | 规范化后唯一 | 人工读写、模型输入序列 |
| InChI | 标准算法 | 标准化层内唯一 | 数据交换、跨库比对 |
| InChIKey | InChI 的哈希压缩 | 理论唯一,工程实践极高 | 数据库索引、网页检索 |
实践经验里有一条不成文的铁律:库内检索与对账用 InChIKey 建索引,给人看和给模型吃用 SMILES,两者并用、各司其职。
背景。1.1 节的化合物对账场景里,最常见的麻烦不是"不同分子",而是"同一分子被写成了不同的字符串"。咖啡因是检验表示系统的经典试金石——结构里有稠环、羰基与甲基化的氮,写法自由度大。
操作。下面五种写法都能在文献与数据库里遇到,我们把它们逐一送进解析器:
from rdkit import Chem from rdkit.Chem import inchi writes = [ "Cn1cnc2c1c(=O)n(C)c(=O)n2C", # 常见教科书式写法 "Cn1c(=O)c2c(ncn2C)n(C)c1=O", # 换一个氮出发遍历,原子顺序完全不同 "CN1C=NC2=C1C(=O)N(C)C(=O)N2C", # 大写非芳香写法,交给解析器自己感知 "Cn1cnc2c1c(=O)n(C)(C)c(=O)n2C", # 多挂一个甲基:满价芳香氮,故意写错 ] keys = set() for w in writes: mol = Chem.MolFromSmiles(w) if mol is None: print("解析失败:", w) # 第四条写法被拦下:价态不合法 continue keys.add(inchi.MolToInchiKey(mol)) print(len(keys)) # 1 —— 前三条合法写法共享同一身份证
结果。第四条写法因为给本已满价的芳香氮多排了一个甲基,在价态校验处被拒绝,MolFromSmiles 返回空——这正是图 2-1 下半段质检的现场演示;前三条写法解析出的分子图同构,InChIKey 全部等于 RYYVLZVUVIJVGH-UHFFFAOYSA-N。
解读。这个结果浓缩了本节的核心直觉:字符串层允许天马行空,身份层必须铁面无私。写法的自由交给 SMILES,比对的重担交给算法生成的标识符。另外注意首段与次段的角色:如果两个 InChIKey 首段相同、次段不同,多半是盐型或电荷差异——检索系统常用这个规律做"同骨架不同盐"的宽松匹配。
变式。把咖啡因换成其互变异构邻居(茶碱、可可碱,各差一个甲基),InChIKey 首段立即不同——标准层不会把甲基差异抹平,该分家的照样分家。反过来,某些互变异构对在标准 InChI 里被有意归一,此时若业务上必须区分互变异构体,就要用带固定氢层的非标准 InChI,并在流程文档里写明选择——标准化不是默认开关,是需要签字确认的业务决策。
c1ccccc1 六个字符全用上了。