如何确保所有正则表达式候选字符串都可以匹配

How to ensure all the regex candidate strings can be matched

在构建匹配候选字符串列表的正则表达式时,如何保证所有的字符串都能被匹配?例如,

这个正则表达式(?:O|SO|S|OH|OS)(?:\s?[-+*°.1-9]){0,4}可以匹配下面所有的例子

O 4 2 -
O 2 - 
SO 4 * - 2 
S 2- 

但是,如果我交换 S 和 SO,生成的正则表达式 (?:O|S|SO|OH|OS)(?:\s?[-+*°.1-9]){0,4} 无法匹配整个 SO 4 * - 2,而是分成两个匹配项:SO 4 * - 2.

所以我的困惑是如何对正则表达式中的候选字符串列表进行排序,从而使它们都安全且唯一匹配?由于我项目中的实际候选字符串列表比示例复杂一点,有没有排序算法可以实现?

您可以添加 \b word boundary assertions 以确保 OS 匹配整个单词。

\b(?:O|S|SO|OH|OS)\b(?:\s?[-+*°.1-9]){0,4}

演示:https://regex101.com/r/xmrZP0/1

The regular expression engine tries to match the alternatives in the order in which they are specified.

那么当模式是 (S|SO) 时?它立即匹配 S 并继续尝试查找匹配项。输入字符串的下一位是无法匹配的 O4*-2

所以,我认为这里的技巧是匹配所有给定的字符串。

(?:O|S)(?:O|H|S)*(?:\s?[-+*°.1-9]){0,4}

演示:https://regex101.com/r/3AwQP7/1

您可以将字符 class 重复 1 次或多次,以防止仅匹配单个大写字符并重新排序备选字符:

\b(?:SO|OS|O[HS]|[SO])(?:\s?[-+*°.1-9]){1,4}

模式匹配:

  • \b 防止部分单词匹配的单词边界
  • (?: 备选方案的非捕获组
    • SO|OS|O[HS]|[SO] 匹配 SO OS OH OS S O
  • )关闭非捕获组
  • (?:\s?[-+*°.1-9]){1,4} 重复 1-4 次可选空白字符和 1 个列出的字符

看到一个regex101 demo.