15

以下是伪示例,不是真正的正则表达式,但仍然是我的意思的示例:


.* (anything)

-.* (NOT anything)

[A-Z] (Any letter A to Z, caps only)

-[A-Z] (NOT any letter A to Z, caps only)

编辑:在问题中将逆改为补。这是进行更改的地方:“将任何正则表达式转换为自身的补充

4

6 回答 6

16

首先,我相信你的意思是正则表达式的补码,而不是它的逆。正则表达式的逆没有多大意义。但如果将其视为一个函数,我想你可以说匹配器的逆是生成所有匹配字符串的生成器 - 或其他东西。另一方面,一种语言的补语是所有那些不在原始语言中的字符串。

那么,这里有两种观点需要考虑:

从根本上说

正则语言的补语是正则的。这意味着可以为补码生成一个接受 DFA(实际上这样做非常简单:只需将非接受状态集与接受状态集交换)。任何这样的 DFA 都可以表示为正则表达式 - 因此原则上您确实可以制作这样的正则表达式。

请参阅有关常规语言的维基百科文章作为起点。

几乎

现在大多数现代语言中使用的典型的与 perl 兼容的正则表达式语法没有补码运算符。对于完整的正则表达式,您可以通过使用负前瞻运算符获得类似的结果:(?!X)将精确匹配字符串何时X不匹配。但是,这是补码运算符的不良替代品,因为您将无法以通常的方式将其用作较大正则表达式的一部分;此正则表达式不“消耗”输入,这意味着它与其他运算符的行为不同。

例如,如果您将数字字符串匹配为[0-9]*, 以匹配您前面^和 append的整个字符串$,但要使用此技术来查找您需要编写的补码^(?!^[0-9]*$).*$- 这种否定正则表达式的通常连接是,如据我所知,无法撤消。

有点讽刺的是,由于反向引用,正则表达式的实际化身理论上更强大,但实际上不太灵活,因为该语言不能很容易地表达补码和交集操作。

于 2010-10-20T16:13:36.207 回答
9

只需运行正则表达式并在逻辑上反转输出。所以改变:

if(/foo/)

至:

if(!/foo/)

字符类可以用前导克拉反转:

[AZ] -> [^AZ]

如果您将说明符大写,许多特殊字符也有反转。

\s whitespace
\S non-whitespace
\w word character
\W non-word-character
\d digit
\D non-digit
于 2010-10-20T11:57:20.360 回答
6

需要考虑的几个变体:

匹配由特定字符集组成的字符串:^[a-z]*$

匹配由特定字符集以外的任何字符组成的字符串:^[^a-z]*$

请注意,有一些快捷方式:

  • \w: 任何字母数字字符(包括_),
  • \W: 任何非字母数字字符;
  • \s: 任何空白字符,
  • \S:任何非空白字符,
  • \d:任何数字,
  • \D: 任何非数字。

这可能会变得非常复杂,例如,如果您想要...

  • 只有非字母:[\d_\W], 或
  • 只有字母:([^\d_\W]即“不是数字,不是 a _,也不是非字母数字字符)

匹配包含子字符串的字符串:^.*substring.*$

匹配包含子字符串的字符串:^(?:(?!substring).)*$

请注意我们必须如何检查字符串中的每个位置是否存在子字符串的“不存在”。您还可以替换任何正则表达式substring来匹配包含或不包含某个子正则表达式的字符串。


匹配任何内容:(.*如果您还想匹配换行符,则必须设置您的编程语言的相应选项,例如re.DOTALL在 Python 中)

如果您不知道如何设置该选项,请匹配任何内容:[\s\S]*

永远不要匹配任何东西(无论出于何种原因):

  • $^(即在字符串开始之前匹配字符串的结尾),
  • \b\B(匹配同时存在单词边界而不是单词边界的位置)或
  • (?!)(匹配一个不可能匹配空字符串的位置)。
于 2010-10-20T12:42:55.740 回答
4

通过使用负前瞻,您将能够处理大多数基本情况

/(?!(OriginalRegex)).*?/
于 2010-10-20T12:25:53.607 回答
3

您的第一个示例没有意义,但对于第二个示例,您可以使用类字符否定:

[a-z] --> [^a-z]
于 2010-10-20T11:54:31.580 回答
1

I am trying to understand the definition of inverse of a regex.

match(input, regular_expression) = {match1, match2, ..., matchN}

How would the inverse work? Should it be something like

match(input, inverse_regular_expression) = {imatch1, imatch2, ..., imatchN}

If so, what is the relationship between the first set of results and the second? If not, then what is it?

于 2010-10-20T12:17:16.130 回答