您需要将负前瞻放在正前:
(?<![A-Z])[A-Z]{3}.(?=[A-Z]{3}(?![A-Z]))
你也可以通过后视来做到这一点:
(?<=(?<![A-Z])[A-Z]{3}).(?=[A-Z]{3}(?![A-Z]))
它不违反“固定长度后视”规则,因为环视本身不消耗任何字符。
编辑(关于固定长度的lookbehind):在所有支持lookbehind 的风格中,Python 是最不灵活的。在大多数风格(例如 Perl、PHP、Ruby 1.9+)中,您可以使用:
(?<=^[A-Z]{3}|[^A-Z][A-Z]{3}).
...匹配前面正好是三个大写 ASCII 字母的字符。第一个选择 - ^[A-Z]{3}
- 开始向后看三个位置,而第二个 - [^A-Z][A-Z]{3}
- 正好向后看四个位置。在 Java 中,您可以将其简化为:
(?<=(^|[^A-Z])[A-Z]{3}).
...因为它在编译时做了一些额外的工作来确定最大后视长度将是四个位置。而在 .NET 和 JGSoft 中,任何事情都会发生;如果它在任何地方都是合法的,那么它在后面是合法的。
但在 Python 中,lookbehind 子表达式必须匹配单个固定数量的字符。如果您多次反对该限制,您可能不会期望这样的事情会起作用:
(?<=(?<![A-Z])[A-Z]{3}).
至少我没有。它比Java版本更简洁;它如何在 Python 中工作?但它确实有效,在 Python 和所有其他支持lookbehind 的风格中。
不,任何形式的前瞻都没有类似的限制。