如何避免正则表达式中的组不匹配?

How can I avoid a group mismatch in regex?

我想在一个简单的编译器中使用正则表达式来检测和匹配标记。 我已经使用这些正则表达式模式来识别标识符和 if/for:

IF_RE = r'[\s]if+?[\s|\(]'
FOR_RE = r'[\s]for+?[\s|\(]'
IDENTIFIER_RE = r'[_a-zA-Z][_a-zA-Z0-9]{0,30}'
MIXED_RE = r'([\s]if+?[\s|\(])|([\s]for+?[\s|\(])|([_a-zA-Z][_a-zA-Z0-9]{0,30})'

但是上面的正则表达式模式的问题在于它检测是否和针对标识符组而不是简单的 if/for。 我的问题是为什么会发生这种情况?我通常如何避免此类问题?

这部分 IDENTIFIER_RE = r'[_a-zA-Z][_a-zA-Z0-9]{0,30}' 也匹配 iffor

您可以使用否定前瞻排除它,排除 if 和 for 后跟单词边界。

IDENTIFIER_RE = r'\b(?!(?:if|for)\b)[_a-zA-Z][_a-zA-Z0-9]{0,30}'

IF_RE = r'[\s]if+?[\s|\(]'FOR_RE = r'[\s]for+?[\s|\(]' 部分匹配前面的强制空白字符,匹配后面的空白字符或 (,也可以只匹配 iffor

这部分例如 f+? 重复 1 次以上匹配一个 f 字符尽可能少,我假设它应该是一个 f

在这两种情况下,您可能会做的是使用 (?<!\S) 断言左侧的空白边界并匹配 0+ 空白后跟 (

IF_RE = r'(?<!\S)if\s*\('
FOR_RE = r'(?<!\S)for\s*\('