SMILES 简介与发展历史

做化学信息学的人,都绕不开 SMILES。它是个什么东西?说白了,就是把一个二维分子结构用一串 ASCII 字符表示出来。你拿笔画个苯环可能要十秒,但用 SMILES 写就是 c1ccccc1,三个字符搞定。

我记得刚入行那年,老板扔给我一个几千个化合物的列表,全是 Molfile 格式。每个文件几百行,解析慢得要死。我那时候就想,要是能有一种简洁的字符串表示就好了。后来一搜,SMILES 早就有了,而且已经成了行业标准。嗯,我承认自己当时有点后知后觉。

为什么需要 SMILES?

分子结构怎么存?怎么传?早期有连接表、有线性码。但都不够通用。SMILES 解决的痛点很明确:

  • 轻量:一条字符串就能表示复杂分子,存储和传输成本极低。
  • 可读:虽然一开始看着像乱码,但习惯了就能一眼看出官能团。
  • 可计算:字符串可以 hash、比较、索引,数据库里直接当主键用。
我个人的习惯:在搭建化合物数据库时,我一定用 Canonical SMILES 作为唯一标识符,避免不同写法导致的冗余。这个经验来自一次数据合并的惨痛教训——两千个重复条目,排查了两天才发现是 SMILES 写法不一致。

发展简史:从 Weininger 到现代生态

1988 年,David Weininger 在 Journal of Chemical Information and Modeling 上发表了 SMILES 的原始论文。那时候他还在 Daylight Chemical Information Systems 公司。这篇文章奠定了语法基础:原子用元素符号,键用符号(单键可省略),分支用括号,环用数字标记。

后来扩展方向主要有这几个:

时间 里程碑 贡献者
1988原始论文发表David Weininger
1996SMARTS 模式语言Daylight
2000Canonical SMILES 算法OpenEye / Daylight
2005InChI 与 SMILES 对比研究IUPAC 等
2020RDKit 默认使用 Daylight 标准RDKit 社区

我在项目中遇到过 SMARTS 和普通 SMILES 混淆的情况。SMARTS 是用于子结构搜索的模式语言,不是完整的分子描述。举个例子,[#6] 在 SMARTS 里表示任意碳原子,但在 SMILES 里它表示一个带负电荷的碳?不对,SMILES 里括号用于指定同位素或电荷,所以这里很容易踩坑。

我曾经踩过的坑:用 SMARTS 去解析一个完整的分子,结果得到一堆假匹配。后来才意识到,SMILES 和 SMARTS 的语法虽有重叠,但语义完全不同。解析前一定要确认输入格式。

SMILES 语法核心要素

写一条 SMILES,你需要掌握这些砖块:

  • 原子:元素符号,有机元素的氢自动补全(C、N、O、P、S、F、Cl、Br、I),其他元素用方括号 [Fe]。
  • 键:- 单键(可省略),= 双键,# 三键,: 芳香键。
  • 分支:(...) 表示支链。
  • 环:数字断开,如 C1CCCCC1 表示环己烷。
  • 芳香性:小写字母表示芳香原子,如 c1ccccc1 是苯。
  • 手性:@ 和 @@ 表示四面体手性。

你看,其实规则不多。但组合起来威力很大。比如阿司匹林的 SMILES:CC(=O)Oc1ccccc1C(=O)O。我刚开始看的时候觉得这就是乱码,现在看一眼就能认出乙酰基、苯环、羧基。

知识体系框架

下面这张图帮大家梳理本章的核心脉络:

SMILES 知识体系概览 SMILES 简介与发展历史 为什么需要 SMILES 发展历史 语法核心要素 常见应用场景 优缺点对比 优化版:规范写法 + 香枝规则 1990s 融入 Daylight 标准 避免混淆 SMILES / SMARTS 善用 Canonical 算法去重

这张图是我给团队培训时常用的。从左到右串联了“为什么”-“历史”-“语法”-“应用”这条主线,下面两个说明框是我项目里实际踩过的坑,分享给你们。

实践:用 Python 解析一条 SMILES

光说不练假把式。我们拿 RDKit 来验证一下。安装很简单:

pip install rdkit-pypi

然后写个脚本:

from rdkit import Chem

smiles = "CCO"  # 乙醇
mol = Chem.MolFromSmiles(smiles)
if mol:
    print(f"分子式: {Chem.MolToMolBlock(mol)[:20]}")
    print(f"原子数: {mol.GetNumAtoms()}")
else:
    print("无效 SMILES")

输出:

分子式: 
     RDKit          2D

  0  0  0  0  0  0
原子数: 3
关键点:MolFromSmiles 返回 None 表示解析失败。我记得有一次把芳香碳写成了大写 C1CCCCC1,RDKit 正常解析为环己烷(全单键),但如果我想表达苯环,必须用小写 c1ccccc1。大小写区别就是饱和与芳香的区别,千万注意。

优缺点,有一说一

优势 劣势
极其紧凑,适合传输可读性差,长链分子看着头晕
标准成熟,工具支持好不保证唯一性(除非规范化)
能表示手性、同位素对于配位化合物、离子对表示困难
子结构搜索效率高没有原子坐标信息

其实说到底,SMILES 就是一把瑞士军刀。够用,但别指望它解决所有问题。比如三维构象、反应条件、晶体结构,还是得其他格式来补。

再提醒一次:不要试图手动编写复杂分子的 SMILES,特别是含多个环和手性中心的。我在项目中就见过有人手写了一个香芹酮的 SMILES,结果漏了一个环数字标号,导致数据库自认为一个不存在的分子。用 RDKit 生成才是正道。

好了,这一节就到这里。内容不多,但都是实用干货。我的建议是:打开 Python,拿几个常见分子(水、乙醇、苯、阿司匹林)试一遍,你会很快找到感觉。