为什么这个正则表达式空间在最后一场比赛?

tob*_*oef 5 regex

我有以下文字:

2 HCl + 12 Na + 3 (Na?Cl?)?? ? 2 NaCl + H?

我想匹配每个分子,包括它的系数.下面的正则表达式几乎正常工作,但是在最后一场比赛之前的空格字符正在匹配,它不应该匹配.这是我正在使用的正则表达式:

(([0-9]* ??\(*([a-z]+[?-?]*)+\)*[?-?]*))

如果您查看此regex101链接,可能更容易看到我的问题:https://regex101.com/r/hK7jY6/1

Wik*_*żew 5

更新

如果你的字符串只是有效的化学公式,为什么还要使用下标/数字/字母呢?有非空白符号.由于必须有必填字母或a (,在字符类中使用它们[a-z(],然后追加\S*(零个或多个非空格):

/(?:\d+ )?[a-z(]\S*/gi
Run Code Online (Sandbox Code Playgroud)

请参阅正则表达式演示.该(?:...)?构建体是可选的非捕获组(即仅用于基,但不能捕获(=在子匹配存储的存储器缓冲器内)的基团.

原始答案解释根本原因

您在开头有数字和空格模式作为可选子模式,相反,您需要强制匹配它们,但放入可选组:

(?:[0-9]+ )?\(*([a-z]+[?-?]*)+\)*[?-?]*
Run Code Online (Sandbox Code Playgroud)

请参阅正则表达式演示

[0-9]* ??变成了一个(?:[0-9]+ )?.请注意,在这里您不必使用延迟版本的?量词,它的工作方式与贪婪的相同.我还删除了2个不必要的外部分组(...).

由于该(?:[0-9]+ )?组是可选的,因此只有在前面有数字时才会匹配空格.如果没有数字,则可以匹配的下一个字符为零或更多(.然后,[a-z]应该出现一个字母(如果没有(,则该字母将是匹配中的第一个字符).

让我分解一下:

  • (?:[0-9]+ )? - 可选的一个或多个数字后跟空格
  • \(*- 零或更多((也许你的意思?)
  • ([a-z]+[?-?]*)+ - 一个或多个字母的零个或多个序列,后跟零个或多个sbscript数字
  • \)*- 零或更多)(也许你的意思?)
  • [?-?]* - 零个或多个下标数字

如果你也想确保你不匹配(Ca或者H),你也应该拆分\(*...\)*是这样的:

(?:[0-9]+ )?(?:(?:[a-z]+[?-?]*)+|\((?:[a-z]+[?-?]*)+\))[?-?]*
Run Code Online (Sandbox Code Playgroud)

另一个演示