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

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

具体来说,我(无可否认有限)的研究使我得到了this posting,它给出了目前公认的化学符号的正则表达式,我将在这里复制以供参考

[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和Cn将通过,但不会通过Cg或Cx.)

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

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

(如果添加起来并不是太麻烦,那么如何人工解析正则表达式的详细描述将会受到极大的赞赏,尽管不是绝对必要的.)

解决方法

简要

我决定为什么不创建一个大规模的正则表达式来做你想要的(但仍然保持一个干净的正则表达式).此正则表达式将与循环结合使用,以检查括号或括号组的匹配项.

假设

由于OP没有给出正面和负面匹配的完整列表,我假设如下:

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

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

回答

View this regex in use here

(?(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)))+$

说明

>(?(DEFINE))部分的第一部分列出了每个周期性元素(按原子序数排序以便于查找).
> Element组充当简单或|在1.中列出的每个元素之间确保每个元素的符号按字母顺序排列第一个字符,然后按符号字符长度排序(以便不捕获,例如,碳C而不是钙Ca)
> ElementGroup以以下格式指定一组化学品:一个或多个元素后跟零个或多个数字,不包括零(由组Num指定)

>有效示例

> C – 元素
> CH – 元素后跟另一个元素
> CH3 -Element后跟另一个Element和Num
> O2 – 元素后跟一个Num

>无效的示例

> N0 – 0不能明确使用
> N01 – Num组指定的数字必须以1-9开头或没有数字
> A – 元素不存在
> c – 元素不存在 – 区分大小写的正则表达式

> ElementParenthesesGroup指定括号()之间但仍包含至少一个ElementGroup的ElementGroup的一个或多个分组

>有效示例

>(CH) – 由括号括起来的ElementGroup
>(CH3) – 括号括起的ElementGroup
>(CH3NO4) – 括号括起的多个ElementGroup
>(CH3N04)2 – 由括号括起的多个ElementGroup,后跟Num

>无效的示例

>(CH [NO4]) – 只有ElementGroup在ElementParenthesesGroup中有效

> ElementSquareBracketGroup指定方括号[]之间的ElementParenthesesGroup或ElementGroup的分组,但包含至少一个ElementParenthesesGroup和另一个组(ElementParenthesesGroup或ElementGroup)

>有效示例

> [CH3(NO4)] – 包含至少一个ElementParenthesesGroup和另一个ElementParenthesesGroup或ElementGroup
> [(NO4)CH] 2 – 包含至少一个ElementParenthesesGroup和另一个ElementParenthesesGroup或ElementGroup,后跟Num
> [(NO4)(CH3)] – 包含至少一个ElementParenthesesGroup和另一个ElementParenthesesGroup或ElementGroup

>无效的示例

> [(NO4)] – 不包含第二组,括号[]是多余的
> [NO4] – 不包含ElementParenthesesGroup

附加信息

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

确保设置以下标志:

> g – 确保全局匹配
> x – 确保忽略空格
>如果数据跨越多行(由换行符分隔),则使用m表示多行

注意:正则表达式只捕获它找到的最后一个类型X(并覆盖先前捕获的所述类型X的组.这是正则表达式的认行为,并且当前无法覆盖此行为.这可能会让您不受欢迎您可以使用链接正则表达式中的最后一个示例以及(CH3)2CFCOO(CH2)2Si(CH3)2Cl的示例来看到这一点,因为每个组类型都有多个.

相关文章

正则替换html代码中img标签的src值在开发富文本信息在移动端...
正则表达式
AWK是一种处理文本文件的语言,是一个强大的文件分析工具。它...
正则表达式是特殊的字符序列,利用事先定义好的特定字符以及...
Python界一名小学生,热心分享编程学习。
收集整理每周优质开发者内容,包括、、等方面。每周五定期发...