用于匹配化学式的严格正则表达式

2023-11-23

在使用 Perl 处理大型文本化学数据库的过程中,我遇到了使用正则表达式来匹配化学公式的问题。我见过these two之前的主题,但建议的答案对于我的要求来说太宽松了。

具体来说,我的(诚然有限的)研究使我发现这个帖子它给出了当前接受的化学符号的正则表达式,我将在此处复制该符号以供参考



[BCFHIKNOPSUVWY]|[ISZ][nr]|[ACELP][ru]|A[cglmst]|B[aehikr]|C[adeflos]|D[bsy]|Es|F[elmr]|G[ade]|H[efgos]|Kr|L[aiv]|M[cdgnot]|N[abdehiop]|O[gs]|P[abdmot]|R[abe-hnu]|S[bcegim]|T[abcehilms]|Xe|Yb
  

(因此例如C, Cm, and Cn会过去,但不会Cg or Cx.)

与前面的问题一样,我还需要匹配数字、完整的括号集和完整的方括号集,以便两个例如C2H6O and (CH3)2CFCOO(CH2)2Si(CH3)2Cl是匹配的。

那么,如何将以前的解决方案与匹配有效化学元素的大正则表达式结合起来,以严格匹配化学式呢?

(如果添加起来不是太麻烦,那么详细说明如何人性化地解析正则表达式将不胜感激,尽管不是绝对必要的。)


Brief

我决定为什么不创建一个巨大的正则表达式来做你想做的事情(但仍然保持一个干净的正则表达式)。该正则表达式将与循环结合使用来检查括号或圆括号组的匹配。


假设

我假设以下内容,因为 OP 没有给出正面和负面匹配的完整列表:

  • 嵌套括号是不可能的
  • 嵌套方括号是不可能的
  • 包围单个括号组的方括号组是多余的,因此不正确
  • 方括号组必须至少包含 2 个组,其中 1 个这样的组必须是括号组

如果这些假设有任何不正确,请告诉我,以便我可以相应地修复正则表达式


Answer

在此处查看正在使用的正则表达式

Code

(?(DEFINE)
  (?# Periodic elements )
  (?<Hydrogen>H)
  (?<Helium>He)
  (?<Lithium>Li)
  (?<Beryllium>Be)
  (?<Boron>B)
  (?<Carbon>C)
  (?<Nitrogen>N)
  (?<Oxygen>O)
  (?<Fluorine>F)
  (?<Neon>Ne)
  (?<Sodium>Na)
  (?<Magnesium>Mg)
  (?<Aluminum>Al)
  (?<Silicon>Si)
  (?<Phosphorus>P)
  (?<Sulfur>S)
  (?<Chlorine>Cl)
  (?<Argon>Ar)
  (?<Potassium>K)
  (?<Calcium>Ca)
  (?<Scandium>Sc)
  (?<Titanium>Ti)
  (?<Vanadium>V)
  (?<Chromium>Cr)
  (?<Manganese>Mn)
  (?<Iron>Fe)
  (?<Cobalt>Co)
  (?<Nickel>Ni)
  (?<Copper>Cu)
  (?<Zinc>Zn)
  (?<Gallium>Ga)
  (?<Germanium>Ge)
  (?<Arsenic>As)
  (?<Selenium>Se)
  (?<Bromine>Br)
  (?<Krypton>Kr)
  (?<Rubidium>Rb)
  (?<Strontium>Sr)
  (?<Yttrium>Y)
  (?<Zirconium>Zr)
  (?<Niobium>Nb)
  (?<Molybdenum>Mo)
  (?<Technetium>Tc)
  (?<Ruthenium>Ru)
  (?<Rhodium>Rh)
  (?<Palladium>Pd)
  (?<Silver>Ag)
  (?<Cadmium>Cd)
  (?<Indium>In)
  (?<Tin>Sn)
  (?<Antimony>Sb)
  (?<Tellurium>Te)
  (?<Iodine>I)
  (?<Xenon>Xe)
  (?<Cesium>Cs)
  (?<Barium>Ba)
  (?<Lanthanum>La)
  (?<Cerium>Ce)
  (?<Praseodymium>Pr)
  (?<Neodymium>Nd)
  (?<Promethium>Pm)
  (?<Samarium>Sm)
  (?<Europium>Eu)
  (?<Gadolinium>Gd)
  (?<Terbium>Tb)
  (?<Dysprosium>Dy)
  (?<Holmium>Ho)
  (?<Erbium>Er)
  (?<Thulium>Tm)
  (?<Ytterbium>Yb)
  (?<Lutetium>Lu)
  (?<Hafnium>Hf)
  (?<Tantalum>Ta)
  (?<Tungsten>W)
  (?<Rhenium>Re)
  (?<Osmium>Os)
  (?<Iridium>Ir)
  (?<Platinum>Pt)
  (?<Gold>Au)
  (?<Mercury>Hg)
  (?<Thallium>Tl)
  (?<Lead>Pb)
  (?<Bismuth>Bi)
  (?<Polonium>Po)
  (?<Astatine>At)
  (?<Radon>Rn)
  (?<Francium>Fr)
  (?<Radium>Ra)
  (?<Actinium>Ac)
  (?<Thorium>Th)
  (?<Protactinium>Pa)
  (?<Uranium>U)
  (?<Neptunium>Np)
  (?<Plutonium>Pu)
  (?<Americium>Am)
  (?<Curium>Cm)
  (?<Berkelium>Bk)
  (?<Californium>Cf)
  (?<Einsteinium>Es)
  (?<Fermium>Fm)
  (?<Mendelevium>Md)
  (?<Nobelium>No)
  (?<Lawrencium>Lr)
  (?<Rutherfordium>Rf)
  (?<Dubnium>Db)
  (?<Seaborgium>Sg)
  (?<Bohrium>Bh)
  (?<Hassium>Hs)
  (?<Meitnerium>Mt)
  (?<Darmstadtium>Ds)
  (?<Roentgenium>Rg)
  (?<Copernicium>Cn)
  (?<Nihonium>Nh)
  (?<Flerovium>Fl)
  (?<Moscovium>Mc)
  (?<Livermorium>Lv)
  (?<Tennessine>Ts)
  (?<Oganesson>Og)
  (?# Regex )
  (?<Element>(?&Actinium)|(?&Silver)|(?&Aluminum)|(?&Americium)|(?&Argon)|(?&Arsenic)|(?&Astatine)|(?&Gold)|(?&Barium)|(?&Beryllium)|(?&Bohrium)|(?&Bismuth)|(?&Berkelium)|(?&Bromine)|(?&Boron)|(?&Calcium)|(?&Cadmium)|(?&Cerium)|(?&Californium)|(?&Chlorine)|(?&Curium)|(?&Copernicium)|(?&Cobalt)|(?&Chromium)|(?&Cesium)|(?&Copper)|(?&Carbon)|(?&Dubnium)|(?&Darmstadtium)|(?&Dysprosium)|(?&Erbium)|(?&Einsteinium)|(?&Europium)|(?&Iron)|(?&Flerovium)|(?&Fermium)|(?&Francium)|(?&Fluorine)|(?&Gallium)|(?&Gadolinium)|(?&Germanium)|(?&Helium)|(?&Hafnium)|(?&Mercury)|(?&Holmium)|(?&Hassium)|(?&Hydrogen)|(?&Indium)|(?&Iridium)|(?&Iodine)|(?&Krypton)|(?&Potassium)|(?&Lanthanum)|(?&Lithium)|(?&Lawrencium)|(?&Lutetium)|(?&Livermorium)|(?&Moscovium)|(?&Mendelevium)|(?&Magnesium)|(?&Manganese)|(?&Molybdenum)|(?&Meitnerium)|(?&Sodium)|(?&Niobium)|(?&Neodymium)|(?&Neon)|(?&Nihonium)|(?&Nickel)|(?&Nobelium)|(?&Neptunium)|(?&Nitrogen)|(?&Oganesson)|(?&Osmium)|(?&Oxygen)|(?&Protactinium)|(?&Lead)|(?&Palladium)|(?&Promethium)|(?&Polonium)|(?&Praseodymium)|(?&Platinum)|(?&Plutonium)|(?&Phosphorus)|(?&Radium)|(?&Rubidium)|(?&Rhenium)|(?&Rutherfordium)|(?&Roentgenium)|(?&Rhodium)|(?&Radon)|(?&Ruthenium)|(?&Antimony)|(?&Scandium)|(?&Selenium)|(?&Seaborgium)|(?&Silicon)|(?&Samarium)|(?&Tin)|(?&Strontium)|(?&Sulfur)|(?&Tantalum)|(?&Terbium)|(?&Technetium)|(?&Tellurium)|(?&Thorium)|(?&Titanium)|(?&Thallium)|(?&Thulium)|(?&Tennessine)|(?&Uranium)|(?&Vanadium)|(?&Tungsten)|(?&Xenon)|(?&Ytterbium)|(?&Yttrium)|(?&Zirconium)|(?&Zinc))
  (?<Num>(?:[1-9]\d*)?)
  (?<ElementGroup>(?:(?&Element)(?&Num))+)
  (?<ElementParenthesesGroup>\((?&ElementGroup)+\)(?&Num))
  (?<ElementSquareBracketGroup>\[(?:(?:(?&ElementParenthesesGroup)(?:(?&ElementGroup)|(?&ElementParenthesesGroup))+)|(?:(?:(?&ElementGroup)|(?&ElementParenthesesGroup))+(?&ElementParenthesesGroup)))\](?&Num))
)
^((?<Brackets>(?&ElementSquareBracketGroup))|(?<Parentheses>(?&ElementParenthesesGroup))|(?<Group>(?&ElementGroup)))+$

解释

  1. 第一部分(?(DEFINE))部分列出了每个周期元素(按原子序数排序以便于查找)。
  2. The Element组充当简单或|在 1 中列出的每个元素之间确保每个元素的符号按第一个字符的字母顺序排序,然后按符号字符长度排序(以免捕获,例如,CarbonC代替钙Ca)
  3. ElementGroup specifies a group of chemicals in the format: one or more Element followed by zero or more digits, excluding zero (specified by the group Num)
    • Valid Examples
      • C - Element
      • CH - Element随后是另一个Element
      • CH3 -Element随后是另一个Element and a Num
      • O2 - Element随后是一个Num
    • Invalid Examples
      • N0 - 0不能明确使用
      • N01 - Numgroup 指定数字必须以1-9或没有号码
      • A- 元素不存在
      • c- 元素不存在 - 区分大小写的正则表达式
  4. ElementParenthesesGroup specifies one or more groupings of ElementGroup between parentheses ( ) but containing at least one ElementGroup
    • Valid Examples
      • (CH) - ElementGroup用括号包围
      • (CH3) - ElementGroup用括号包围
      • (CH3NO4)- 多种的ElementGroup用括号包围
      • (CH3N04)2- 多种的ElementGroup用括号括起来,后跟Num
    • Invalid Examples
      • (CH[NO4]) - Only ElementGroup里面有效ElementParenthesesGroup
  5. ElementSquareBracketGroup specifies a grouping of ElementParenthesesGroup or ElementGroup between square brackets [ ] but containing at least one ElementParenthesesGroup and one other group (ElementParenthesesGroup or ElementGroup)
    • Valid Examples
      • [CH3(NO4)]- 至少包含一个ElementParenthesesGroup和另一个ElementParenthesesGroup or ElementGroup
      • [(NO4)CH]2- 至少包含一个ElementParenthesesGroup和另一个ElementParenthesesGroup or ElementGroup其次是Num
      • [(NO4)(CH3)]- 至少包含一个ElementParenthesesGroup和另一个ElementParenthesesGroup or ElementGroup
    • Invalid Examples
      • [(NO4)]- 不包含第二组、括号[ ]是多余的
      • [NO4]- 不含ElementParenthesesGroup

附加信息

我意识到这是一个很长的答案,但 OP 提出了一个非常具体的问题,并希望确保满足特定的标准。

确保设置以下标志:

  • g- 确保全球匹配
  • x- 确保忽略空白
  • 如果数据跨多行(用换行符分隔)使用m对于多线

注意:正则表达式只会捕获最后一组类型X它找到(并覆盖先前捕获的所述类型的组)X。这是正则表达式的默认行为,当前无法覆盖此行为。这可能会给您带来不良结果。您可以通过链接的正则表达式中的最后一个示例以及您的示例看到这一点(CH3)2CFCOO(CH2)2Si(CH3)2Cl因为每种组类型都有多个。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

用于匹配化学式的严格正则表达式 的相关文章

  • 正则表达式仅匹配字母

    如何编写仅匹配字母的正则表达式 使用字符集 a zA Z 匹配 A Z 中的一个小写和大写字母 a zA Z 匹配一个或多个字母并且 a zA Z 仅匹配仅由一个或多个字母组成的字符串 and 分别标记字符串的开始和结束 如果您想匹配除 A
  • 如何使用 string#split 用分隔符 + - * / ( ) 和空格分割字符串并将它们保留为额外标记?

    我需要拆分包含基本数学表达式的字符串 例如 a b c or a c d 分隔符是 和空格 我需要它们作为独立的标记 基本上结果应该是这样的 a b c 对于第二个例子 a 我读了很多关于具有不太复杂的分隔符的类似问题的问题 常见的答案是使
  • 在 Perl 中实现 CLI 工具的最佳实践是什么?

    我正在使用 Perl 实现 CLI 工具 我们可以遵循哪些最佳实践 作为前言 我花了 3 年时间为一家大型金融公司设计并实现了一个相当复杂的 Perl 命令行工具集 以下想法基本上是我们团队设计指南的一部分 用户界面 命令行选项 允许尽可能
  • 使用 awk 将特定子字符串与正则表达式匹配

    我正在处理特定的文件名 并且需要从中提取信息 文件名的结构类似于 20100613 M4 28007834 005 F RANDOMSTR raw gz RANDOMSTR 是最多 22 个字符的字符串 并且可能包含 或不包含 格式为 W
  • Python 中的正则表达式替换:将命名组转换为整数

    替换字符串中的模式时 我特别需要匹配命名组的整数 长整型值 案例示例和我尝试过的方法 status 1 foo 23 bar re sub
  • Mercurial .hgignore 负向前瞻

    使用 Mercurial 我需要忽略除名为 keepers 的某个目录中的文件之外的所有文件 从表面上看 使用 Regex 和 Negative Lookahead 似乎很容易 然而 尽管我能够在 Regex Buddy 和其他工具中验证我
  • 在评论中查找不同风格的日期

    我还有一个问题要问preg match 我有一个表 其中评论的日期写在评论本身内 手动 现在我需要提取该日期并将其放置在不同的列中 我发现评论和日期的样式如下 id warning sent warning date 6109 2011 0
  • 排除正则表达式匹配中的字符串,以进行 sed 处理

    我需要将其匹配为替代命令 whatever MATCH THIS whateverwhatever AND THIS whateverwhatever 我正在尝试 sed e s 1 g myfile 但这是急切的匹配 MATCH THIS
  • Perl:散列 2 中数组的数值排序(施瓦茨变换)

    这实际上是该线程的后续内容 Perl 散列中数组的数字排序 https stackoverflow com questions 7914931 perl numerical sort of arrays in a hash 我无法编辑原始问
  • htaccess 重写以包含 #!

    呼叫所有 htaccess 专家 我需要你的帮助 我正在尝试强制重写以包含 在网址中 所以基本上我需要 http example com biography http example com biography 将被重写为http exam
  • 将整个单词与特殊字符匹配的正则表达式不起作用? [复制]

    这个问题在这里已经有答案了 我正在经历这个问题C Regex Match 整个单词 https stackoverflow com q 1209049 443568 它说要匹配整个单词使用 b模式 b 这对于匹配没有任何特殊字符的整个单词效
  • 零垫重命名,例如图片 (2).jpg -> 图片 (002).jpg

    我需要按照标题在所有子文件夹中解释的方式重命名所有图像 我正在考虑用正则表达式提取括号内的数字 然后重命名它 搜索周围我看到有类似的工具rename and mmv但我无法让他们重新命名 jpg 我将不胜感激任何解决我的问题的建议 顺便说一
  • 捕获长字符串上的特定字段[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我有点卡在这里 我正在努力解析一些如下所示的信息 CouchDB 数据库内容 rows id AGO key AGO value re
  • 正则表达式匹配一个单词后不跟其他两个单词

    我有一些链接 utmcsr rdstation utmccn curso intro coaching utmcmd inbound utmctr link3 utmcsr rdstation utmccn agenda psc utmcm
  • 使用 regEx 验证属性名称

    我想使用点表示法规则 任何字母或数字以及 and 只要它不以数字开头 显然如果使用括号表示法那么一切都是有效的 我一直在尝试找出正则表达式解决方案 但我对正则表达式的了解并不多 我认为我当前的模式将允许字母 数字 and 但我不知道如何禁止
  • 如何在 Perl 中将多个哈希值合并为一个哈希值?

    在 Perl 中 我如何得到这个 VAR1 999 gt 998 gt 908 906 0 998 907 VAR1 999 gt 991 gt 913 920 918 998 916 919 917 915 912 914 VAR1 99
  • 缓存施瓦茨变换

    我正在学习 中级 Perl 它非常酷 我刚刚读完 施瓦茨变换 部分 在理解它之后 我开始想知道为什么变换不使用缓存 在具有多个重复值的列表中 转换会重新计算每个值的值 因此我想为什么不使用哈希来缓存结果 这是一些代码 a place to
  • 正则表达式替换以删除空格并将逗号更改为句点

    我有以下价值观 10 000 00 10 000 00 750 00 750 00 1 000 000 00 1 000 000 00 并需要以下结果 10000 00 10000 00 750 00 750 00 1000000 00 1
  • 如何在 Perl 中运行匿名函数?

    sub print 1 sub print 1 我尝试了各种方法 都是错误的 sub 将为您提供指向该函数的指针 因此您必须通过引用调用 sub print Hello world n gt 另一种简单的方法 如所指出的布拉戈维斯特 布尤克
  • 在 Perl 中查找标量变量的数据类型

    我有一个接受用户输入的函数 输入可以是整数 浮点数或字符串 我有三个重载函数 应该根据输入数据的数据类型调用它们 例如 如果用户输入一个整数 比如100 则应该调用具有整数参数的函数 如果用户输入字符串 例如 100 则应调用具有字符串参数

随机推荐

  • 带睡眠和不带睡眠的递归异步

    我有两个版本的异步函数 async function asyncRecurseOne i try console log i i i 1 await asyncRecurseOne i catch ex console log ex asy
  • 将元胞数组的元胞数组转换为矩阵的矩阵

    我可以将矩阵元胞数组转换为矩阵 gt gt C 1 1 2 2 3 3 gt gt cell2mat C ans 1 1 2 2 3 3 还行吧 但是 我想将包含其他元胞数组的元胞数组转换为矩阵 gt gt C 1 1 2 2 3 3 gt
  • 使用 Powershell 查找文件中的多行模式

    如何使用 Powershell 在文件中查找多行模式 例如 XML 节点的内容 也就是说 如果我正在寻找 绿色 这个词deviceDescription节点 但 XML 节点文本可能跨越多行 这是行不通的 dir r i xml selec
  • 单击动态链接时深层链接不包含有效的必需参数

    我已将动态链接设置为文档 但单击链接时它显示 Deep Link does not contain valid required params URL params cpb 1 cpt cpit fpb CJsFEPcCGgVlbi1VUw
  • Azure AD B2C 向新用户发送邀请电子邮件

    通过使用新的 Azure AD B2C 服务预览版 我希望能够向用户发送邀请电子邮件以完成 SaaS 应用程序的注册 我们的每个客户都将管理自己的用户 我希望他们能够向新用户生成邀请电子邮件 以访问我们的 SaaS 应用程序 然后该用户将完
  • 字符串形式的月份名称

    我试图以字符串形式返回月份名称 例如 五月 九月 十一月 I tried int month c get Calendar MONTH 但是 这会返回整数 分别为 5 9 11 如何获取月份名称 用这个 Calendar cal Calen
  • Azure devops 报告生成器任务找不到coverage.cobertura.xml 文件

    正如标题所示 我正在尝试让代码覆盖率在 Azure Devops Pipeline 上运行 这是管道 trigger master pool vmImage windows latest variables solution sln bui
  • 我可以运行受密码保护的只读 git 服务器吗?

    我需要一个应用程序能够从 git 存储库获取但不能推送到它 所以 这是只读部分 这可以通过 git daemon 轻松完成 最重要的是 我需要访问受密码保护的所述存储库 包括读取它 因此 在进行任何获取之前 应用程序需要进行身份验证 可行吗
  • 为什么 null 是一个对象,null 和 undefined 有什么区别?

    Why is null被认为是object在 JavaScript 中 正在检查 if object null Do something 与 if object Do something 并且 有什么区别null and undefined
  • 使用需要不记名令牌的 API 在 Python 中进行 API 调用

    寻求有关将 JSON API 调用集成到 Python 程序中的帮助 我希望将以下 API 集成到 Python py 程序中 以允许调用它并打印响应 API 指南指出必须生成不记名令牌才能允许调用 API 我已成功完成此操作 但是 我不确
  • 有没有办法用 simple_form for Rails 提交 ajax/json 请求

    使用标准 Rails form for 我能够通过 select 和 collection select 帮助器传递 ajax 请求 如下所示 我似乎不知道如何做到这一点简单的形式 弄清楚了 你只需要添加这个 input html gt d
  • 使用 controlTransfer 方法设置奇偶校验

    有人知道如何在 Android 中设置与 controlTransfer 的奇偶校验吗 我在任何地方都找不到此方法参数的解释 只是参考文献中的一些通用信息 我发现的一个例子说 conn controlTransfer 0x40 0x04 0
  • 浮点文字与浮点变量的奇怪编译器行为

    我注意到 C 编译器的浮点舍入 截断有一个有趣的行为 也就是说 当浮点文字超出保证的可表示范围 7 位十进制数字 时 a 将浮点结果显式转换为浮点 语义上不必要的操作 和 b 将中间计算结果存储在局部变量中都会更改输出 一个例子 using
  • Heroku 和 GitHub:“无法检索项目,内部服务器错误”

    这篇文章涉及一个快速变化的事件 我只想连接到我的 GitHub 帐户 当我执行此操作时 我会在页面右上角收到以下红色小弹出窗口的错误消息 无法检索项目 内部服务器错误 截至 2022 年 5 月 25 日 19 52 世界标准时间 GitH
  • 比较两个列表的更新、删除和添加

    简单的问题 我有一个新列表和一个旧列表 在Java中是否有一个标准的方法 库允许我比较这两个列表并确定哪些项目已更新 删除或全新 例如 我最终应该得到三个列表 已删除的项目 旧的项目但不是新的项目 更新的项目 两者中的项目 新项目 新的项目
  • 如何使用 Dapper-dot-net 从单个 SP 映射多个记录

    我想在执行单个存储过程将返回 50 个多个单独的选择的情况下使用 Dapper 每个结果集都不会很宽 最多可能有 20 或 30 列 下面的代码来自 Dapper 测试 我想知道这个示例是否是一个很好的原型 谢谢你 斯蒂芬 public v
  • PHP Curl 下载前检查文件是否存在

    我正在编写一个 PHP 程序 从后端下载 pdf 并保存到本地驱动器 现在如何在下载前检查文件是否存在 目前我正在使用curl 参见下面的代码 来检查和下载 但它仍然下载大小为1KB的文件 url http wedsite test pdf
  • 当我们声明静态变量时,编译器实际上做了什么?

    我想知道幕后到底发生了什么 编译器如何处理静态变量 与自动变量不同 静态变量的值即使在块结束后仍然存在 但是编译器实际上如何处理这个问题 与堆栈上的局部变量不同 静态变量保存在特殊的数据段中 静态变量转到哪个段取决于它们是否初始化为 0 0
  • 跨平台和语言(反)序列化

    我正在寻找一种以最方便的方式序列化一堆 C 结构的方法 以便序列化可以跨 C 和 Java 至少 以及跨 32 位 64 位 大 小端平台移植 要序列化的结构仅包含数据 即它们是没有状态或行为的纯数据对象 我们的想法是 我们将结构序列化为一
  • 用于匹配化学式的严格正则表达式

    在使用 Perl 处理大型文本化学数据库的过程中 我遇到了使用正则表达式来匹配化学公式的问题 我见过these two之前的主题 但建议的答案对于我的要求来说太宽松了 具体来说 我的 诚然有限的 研究使我发现这个帖子它给出了当前接受的化学符