正则表达式字符间隔异常

Regex character interval with exception

假设我有一个包含字符 ['A'-'Z'] 的区间,我想匹配除字母 'F' 之外的每个字符,我需要通过 ^ 运算符来完成。因此,我不想将它分成两个不同的区间。

我怎样才能做到最好?我想写类似 ['A'-'Z']^'F' 的东西(A-Z 之间的所有字符,字母 F 除外)。这个站点可以作为参考:http://regexr.com/

编辑: 与 ocaml 的关系是我想在 ocamllex 中定义一个字符串文字的正则表达式,starts/ends 带有双引号( " )并采用允许在一定范围内的字符。因此我想排除双引号,因为它显然结束了字符串。(我暂时不考虑转义字符)

(?!F)[A-Z]((?!F)[A-Z])*

这将匹配每个大写字符,不包括 'F'

由于很难找到两个正则表达式语法完全相同的正则表达式库/处理器,因此始终准确指定您使用的系统非常重要。

问题中的标签让我相信您可能正在使用 ocamllex 构建扫描仪。在这种情况下,根据其 regular expression syntax 的文档,您可以使用

['A'-'Z'] # 'F'

这大致基于 flex:

中使用的语法
[A-Z]{-}[F]

Java 和 Ruby 正则表达式包括语法非常不同的类似运算符:

[A-Z&&[^F]]

如果您使用的正则表达式库包括 negative lookahead assertions (Perl, Python, Ecmascript/C++ 等),您可以使用其中之一:

(?!F)[A-Z]

或者您可以结合使用肯定的先行断言和否定字符 class:

(?=[A-Z])[^F]

在这个简单的例子中,这两个结构有效地做了一个连词,但环视断言并不是真正的连词。对于实现合取运算符的正则表达式系统,请参见 Ragel.

下面的正则表达式使用 ^ 完成了您想要的,并且没有分成不同的间隔。它还重新定义了您最初的想法 (['A'-'Z']^'F')。

/(?=[A-Z])[^F]/ig

如果只允许大写字母,只需删除 i 标志。

Demo

使用字符class减法:

[A-Z&&[^F]]

[A-EG-Z] 的替代方案是 "OK" 用于单个异常,但当存在许多异常时会很快崩溃。考虑辅音(非元音)的这个简洁表达:

[B-Z&&[^EIOU]]

对比这列火车残骸

[B-DF-HJ-NP-TV-Z]

字符集差异的 ocamllex 语法是:

['A'-'Z'] # 'F'

相当于

['A'-'E' 'G'-'Z']