我有以下文字:
2 HCl + 12 Na + 3 (Na₃Cl₂)₂₄ → 2 NaCl + H₂
我想匹配每个分子,包括它的系数。下面的正则表达式几乎正常工作,但是在最后一场比赛之前的空格字符正在匹配,它不应该是。这是我正在使用的正则表达式:
(([0-9]* ??\(*([a-z]+[₀-₉]*)+\)*[₀-₉]*))
如果你看看这个regex101链接,可能更容易看出我的问题是什么: https://regex101.com/r/hK7jY6/1
答案 0 :(得分:5)
如果您的字符串只是有效的化学公式,为什么还要使用下标/数字/字母呢?有非空白符号。由于必须有必填字母或(
,请在字符类[a-z(]
中使用它们,然后附加\S*
(零个或多个非空格):
/(?:\d+ )?[a-z(]\S*/gi
请参阅regex demo。 (?:...)?
构造是一个可选的非捕获组(即,仅用于分组但不捕获的组(=将子匹配存储在内存缓冲区中)。
您在开头有数字和空格图案作为可选子图案,相反,您需要强制匹配它们,但放入可选组:
(?:[0-9]+ )?\(*([a-z]+[₀-₉]*)+\)*[₀-₉]*
请参阅regex demo
您的[0-9]* ??
已变为(?:[0-9]+ )?
。请注意,在这里您不必使用惰性版本的?
量词,它的工作方式与贪婪的一样。我还删除了2个不必要的外部分组(...)
。
由于(?:[0-9]+ )?
组是可选的,因此只有前面有数字时才会匹配空格。如果没有数字,则可以匹配的下一个字符为零或更多(
。然后,应该出现[a-z]
个字母(如果没有(
,则该字母将是匹配中的第一个字符。)
让我分解一下:
(?:[0-9]+ )?
- 可选的一个或多个数字后跟空格\(*
- 零或更多(
(也许您的意思是?
)([a-z]+[₀-₉]*)+
- 一个或多个字母的零个或多个序列,后跟零个或多个sbscript数字\)*
- 零或更多)
(也许您的意思是?
)[₀-₉]*
- 零个或多个下标数字如果您还想确保自己不匹配(Ca
或H)
,还应该像这样分割\(*...\)*
:
(?:[0-9]+ )?(?:(?:[a-z]+[₀-₉]*)+|\((?:[a-z]+[₀-₉]*)+\))[₀-₉]*
请参阅another demo
答案 1 :(得分:2)
虽然Wiktor的回答非常有用,但我想我可能已经找到了一种更简单的方法。
([0-9]+ )*[a-z\(₀-₉\)]+
就我所知,这将与等式的所有部分相匹配。
<强>更新强>
请参阅Wiktors更新答案,它比这更好。