SMILES 简介:规则、语法与常见示例
大家好,我是这门课的主讲人。今天咱们来聊聊 SMILES——这东西看着像一串乱码,但其实是化学信息学的基石。我记得刚入行那会儿,第一次看到 CC(=O)O 时完全懵了,心想醋酸怎么长这样?后来才发现,一旦读懂了规则,它就是最优雅的分子「身份证」。
什么是 SMILES?
SMILES 全称是 Simplified Molecular Input Line Entry System,说白了就是一种用 ASCII 字符串描述分子结构的线性表示法。它由 David Weininger 在 1980 年代提出,现在已经是化学信息学、药物发现、分子生成模型中最通用的「语言」之一。
我个人习惯把它理解为:把一张 2D 结构图压缩成一行文本。这个过程依赖一个确定性算法——先选出起点原子,再按深度优先遍历记录连接顺序、分支、环和立体信息。你可能会问:「为什么不直接用图数据库或 SMARTS?」嗯,SMILES 的强项在于简洁——一个字符串就能唯一标识一个分子(不考虑不规范写法时),而且非常便于机器处理和模型输入。
SMILES 表示法核心规则
下面这些规则,我在项目里踩过不少坑,一个个说。
原子表示
- 有机元素直接用元素符号:
C、O、N、P、S、F、Cl、Br、I。 - 其他元素用方括号括起来,比如
[Fe]、[Au]。 - 氢原子通常省略——除非你显式要写同位素或电荷,比如
[2H](氘)。 - 电荷写在方括号里:
[NH4+]表示铵根。
Co 当成「C」和「O」两个原子处理——结构全乱了。记住:所有非有机元素都得加方括号!
键与连接
- 单键直接用
-,但在大多数情况下可以省略。比如CC就是乙烷。 - 双键用
=,三键用#。 - 芳香键用
:或小写字母表示(详见「芳香性」小节)。
举个例子:乙醛是 CC=O,丙酮是 CC(=O)C——注意括号表示分支。
分支
分支用圆括号 () 表示。规则很简单:遇到分支,就把支链写在挂载点的后面,并用括号括起来。例如异丁烷:CC(C)C。你可以嵌套分支:一个支链上再挂一个支链,比如 CC(C)(C)C(新戊烷)。
环
环结构通过数字标记闭合。每个环的开头原子和结尾原子用同一个数字标记,比如环丙烷是 C1CC1。数字从 1 开始,可以重复使用(同一个环用同一个数字)。多个环用不同数字,比如二环的萘:C1=CC=C2C=CC=CC2=C1。
我记得有一次训练生成模型,输出的 SMILES 里环数字匹配错了——比如 C1CC2C3 数字没配对,导致后处理无法复原分子结构。所以写 SMILES 时一定要保证:每个数字出现且仅出现两次。
芳香性
芳香环用小写字母表示,例如苯是 c1ccccc1 而不是 C1=CC=CC=C1。小写字母暗示芳香性,解析器会自动分配 Delocalization。注意:只对 C、N、O、S、P 有效,且必须是环内共轭体系。
c1ccccc1 和 C1=CC=CC=C1 在 canonicalization 下可能被视为不同字符串。生成模型里这种不一致会直接降低准确率!
立体化学
SMILES 支持两种立体信息:
- 顺反异构:用
/和\表示双键两侧的原子排列。例如顺-2-丁烯:C/C=C\C。 - 手性中心:用
@表示四面体方向。@表示逆时针,@@表示顺时针。比如 L-丙氨酸的 SMILES:C[C@@H](C(=O)O)N。
我个人的经验是:手性符号特别容易写反。如果你在纸上画费歇尔投影,建议先把构型转换为 3D 坐标,再用 Open Babel 或 RDKit 生成规范 SMILES——比手写安全得多。
常见分子 SMILES 示例
下面这张表我精心挑了几个典型分子,涵盖不同结构特征:
| 分子名称 | SMILES | 结构特点 |
|---|---|---|
| 甲烷 | C | 单原子表示 |
| 乙醇 | CCO | 链状,含羟基 |
| 乙酸 | CC(=O)O | 支链 + 双键 |
| 环己烷 | C1CCCCC1 | 简单位环,数字闭合 |
| 苯 | c1ccccc1 | 芳香环,小写 |
| 咖啡因 | CN1C=NC2=C1C(=O)N(C(=O)N2C)C | 多环 + 分支 + 双键 + 甲基 |
看到咖啡因的 SMILES 了吧?它包含了括号嵌套环、双键和多个甲基,写起来很考验耐心。我当时做分子生成时,经常用这个分子来测试模型的环闭合能力。
知识体系概览
下面的流程图梳理了 SMILES 的核心语法要素及它们之间的关系——从原子到键、分支、环、芳香性与立体。你写 SMILES 时按这个顺序检查,基本不会漏。
你可以把这个图当作检查清单。我在用 RDKit 解析 SMILES 之前,总会先把字符串按这几个要素过一遍——原子对吗?键对了吗?环数配对了吗?立体符号匹配吗?走完流程再交给代码,能省掉大半天的调试时间。
小结与建议
SMILES 看上去是简单的文本,但背后依赖一套严格的语法。我个人建议:编写生成模型时,统一使用规范化的 SMILES(比如 RDKit 的 MolToSmiles(mol, canonical=True)),避免引入 C1=CC=CC=C1 和 c1ccccc1 这种「等价异形」字符串——不然模型会被绕晕。另外,遇到复杂环系或手性分子,一定多跑几个测试用例确认前后端解析一致。
python -c "from rdkit import Chem; m=Chem.MolFromSmiles('你的SMILES'); print(Chem.MolToSmiles(m))" 快速规范化。这个命令我几乎每天都会用。