SMILES 简介:化学分子线性表示法

做化学信息学的人,每天都得跟分子结构打交道。你想想看,一个有机分子动不动就几十上百个原子,怎么在计算机里存它?画个图?那文件太大了,也不方便搜索。早年我还在药企做数据库的时候,每天要处理几百万个分子,要是都用 MOL 文件存,硬盘早炸了。

后来我遇到了 SMILES——Simplified Molecular Input Line Entry System。说白了,就是把分子结构写成一行字符串。就像给分子起了个“身份证号”,简短、唯一、还能还原成结构。

SMILES 的核心思想:用 ASCII 字符表示原子、化学键、分支和环。一行字符串 = 一个完整的分子。

为什么不能用分子图?

分子图(Graph)虽然直观,但存储和计算成本太高。举个例子:乙醇的分子图包含 9 个原子和 8 条键,存成图结构至少要几百字节。而 SMILES 只需要 3 个字符:CCO。你自己感受一下差别。

我刚开始做分子指纹计算时,读了几万个 MOL 文件,程序卡得跑不动。后来全部转成 SMILES,处理速度提升了 100 倍。嗯,从那时起,我就成了 SMILES 的铁粉。

SMILES 的基本规则

SMILES 的语法其实不复杂,掌握几个核心点就够了。我们来拆开看。

1. 原子表示

  • 标准元素符号:直接写元素周期表的符号。比如 C 是碳,O 是氧,N 是氮。
  • 特殊原子:带电荷、同位素或配位数的原子,用方括号括起来。比如 [NH4+] 表示铵根离子,[13CH3] 表示碳-13 同位素的甲基。
  • 氢原子:大多数情况下省略。比如 CH3 表示甲基,不用写成 C 加三个 H。
  • 芳香性原子:用小写字母表示。比如 c1ccccc1 就是苯环,中间的 c 都是芳香碳。

这里有个坑:我当年写 SMILES 时,把氟原子写成了 F 就对了,但氯原子不能写 CL,必须写 Cl。元素符号大小写很敏感,搞错了解析器会报错。

2. 化学键表示

键类型符号示例
单键- 或不写CC(乙烷)
双键=C=C(乙烯)
三键#C#C(乙炔)
芳香键:c1ccccc1(苯环)

你没看错,单键可以不写。比如乙醇写 CCO,中间的单键直接省略。但有时候写全 C-C-O 也行,只是代码长了点。

3. 分支结构

分支用圆括号 () 表示。比如异丙醇:CC(C)O。括号里的 C 就是挂在中间碳上的甲基分支。你可以想象成:先写骨干,再用括号把支链“挂”上去。

我曾经犯过的错误:写 CC(C)O 想把甲基挂在左边的碳上,结果解析器默认挂到右边的碳上。其实 SMILES 的分支是 挂在前一个原子上的,搞反了结构就错了。

4. 环结构

用数字标记环的起点和终点。比如环己烷:C1CCCCC1。数字 1 表示第一个环的断开处,前后两个 1 连接起来就形成了闭环。多个环用不同的数字,比如萘:c1ccc2ccccc2c1,用了 1 和 2 两个环标签。

小技巧:如果分子里环数很多,建议用 %...% 语法来写两位数的环标签,比如 %10% 表示第 10 个环。否则数字超过 9 就和原子符号混淆了。

5. 电荷与同位素

  • 电荷写在方括号里:[Na+]、[Cl-]、[OH-]。
  • 同位素写在元素符号前面:[18OH2] 表示 H218O。
  • 配位键/离子键有时用 [Fe+3] 等形式表示。

6. 芳香性

芳香碳用小写 c,芳香氮用小写 n,芳香氧用小写 o。比如吡啶:n1ccccc1。芳香键用 : 表示,但绝大多数时候你只用小写原子符号,解析器会自动识别芳香键。

SMILES 到底长什么样?看几个例子

下面是我随手列的几个常见分子的 SMILES,你可以对照结构感受一下。

# 乙醇
CCO

# 苯
c1ccccc1

# 环己烷
C1CCCCC1

# 乙酸(醋酸)
CC(=O)O

# 对硝基苯酚
c1cc(ccc1[N+](=O)[O-])O

# 咖啡因
Cn1c(=O)c2c(ncn2C)n(C)c1=O

注意看乙酸的写法:CC(=O)O。那个 =O 表示双键氧,括号里的 =O 是分支。如果不加括号,写成 CC=O 就成了乙醛,完全不一样。

SMILES 与其他表示法的对比

格式优点缺点
SMILES紧凑、易读、适合文本处理不唯一(同分子有多种写法)
Canonical SMILES唯一标准形式需要标准化算法
MOL/SDF保留原子坐标和键信息文件大,不适合大规模存储
InChI标准化强,含立体化学字符串很长,不易读

我一般这么选:做数据库用 Canonical SMILES,做可视化用 MOL 文件,做唯一标识用 InChI。SMILES 可读性最好,调试时特别方便。

注意:不是所有分子都能用 SMILES 完美表示。比如多聚体、配位键、部分金属有机化合物,SMILES 的语法会变得很别扭。这时候可以改用 *.MOL 或专用标记方法。

从分子到 SMILES:用 Python 搞定

写 SMILES 当然不用手撸,RDKit 这个库帮你干脏活。下面是我经常用的几行代码:

from rdkit import Chem

# 从 SMILES 读入分子
mol = Chem.MolFromSmiles("CCO")
print(mol.GetNumAtoms())  # 输出 3

# 从分子转 SMILES
smiles = Chem.MolToSmiles(mol)
print(smiles)  # 输出 CCO

# 转成 Canonical SMILES(唯一的)
canon_smiles = Chem.MolToSmiles(mol, canonical=True)
print(canon_smiles)  # 还是 CCO,因为乙醇本身很简单

你看,三行代码搞定了。但注意:RDKit 的 Canonical SMILES 默认会做一些标准化,比如将芳香性写成小写。如果你要保留原始写法,可以加参数 isomericSmiles=True 或 allBondsExplicit=True。

SMILES 知识体系

下面这张图把 SMILES 的核心元素串了起来。看完这张图,你就能理解它为什么叫“线性表示法”了。

SMILES 语法元素结构 SMILES 字符串 原子符号 化学键 分支 ( ) 环数字 1/2 芳香性小写 电荷/同位素 [ ] 说明:SMILES 用纯文本表示分子结构。核心是原子符号, 然后用键、分支、环、电荷等修饰符描述连接关系。 解析时从左到右依次读取,括号表示分支,数字表示环。

常见避坑指南

  • 大小写必须严格:氮元素写 N,不能写 n(除非是芳香氮)。溴写 Br,不能 BR。
  • 环数字不能重复使用:一个分子里如果出现两个相同数字,解析器会认为它们必须连在一起。如果你只是巧合写了个 C1C1,那是错误。
  • 分支括号紧贴前一个原子:CC(C)O 和 C C ( C ) O 都是合法的,但前者更规范。不要瞎加空格。
  • 芳香性表示要一致:要么都用小写(如 c1ccccc1),要么都用大写加芳香键 c1:c:c:c:c:c1。混着用容易出问题。

我的习惯:拿到一个分子后,先用 RDKit 的 MolFromSmiles() 验证一下,再转成 Canonical SMILES。这样能避免手写错误,也保证唯一性。

SMILES 看起来简单,但它是整个化学信息学大厦的砖瓦。你在后面会遇到 SMILES token 化、注意力机制、热力图可视化——所有这些都建立在你能正确读写 SMILES 的基础上。这一章打好了地基,后面你就能盖起高楼了。