在使用 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)))+$
解释
- 第一部分
(?(DEFINE))
部分列出了每个周期元素(按原子序数排序以便于查找)。
- The
Element
组充当简单或|
在 1 中列出的每个元素之间确保每个元素的符号按第一个字符的字母顺序排序,然后按符号字符长度排序(以免捕获,例如,CarbonC
代替钙Ca
)
-
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
- Num
group 指定数字必须以1-9
或没有号码
-
A
- 元素不存在
-
c
- 元素不存在 - 区分大小写的正则表达式
-
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
-
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(使用前将#替换为@)