以下是伪示例,不是真正的正则表达式,但仍然是我的意思的一个例子:
.* (anything)
-.* (NOT anything)
[A-Z] (Any letter A to Z, caps only)
-[A-Z] (NOT any letter A to Z, caps only)
编辑:在问题中将逆转换为补码。这是改变的地方:“将任何正则表达式转换为补充本身”
答案 0 :(得分:12)
首先,我相信你的意思是正则表达式的 补充 ,而不是它的反面。正则表达式的倒数没有多大意义;但是如果把它视为一个函数,我想你可以说匹配器的逆是生成所有匹配字符串的生成器 - 或者其他东西。另一方面,语言的补充是原始语言中不的所有字符串。
然后,这里有两个观点需要考虑:
常规语言的补充是常规的。这意味着可以为补码生成一个接受的DFA(这样做非常简单,实际上:只需将非接受状态集与接受状态集交换)。任何这样的DFA都可以表示为正则表达式 - 所以原则上你确实可以制作这样的正则表达式。
请参阅Regular Languages上的维基百科文章作为起点。
现今大多数现代语言中使用的典型perl兼容正则表达式语法没有互补运算符。对于完整的正则表达式,您可以通过使用否定前瞻运算符来获得类似的内容:(?!X)
将在X
不匹配时精确匹配字符串。但是,这对补码运算符来说是一个很差的替代品,因为你无法以通常的方式将它用作更大的正则表达式的一部分;这个正则表达式不会“消耗”输入,这意味着它与其他运算符一起表现不同。
例如,如果您将数字字符串与[0-9]*
匹配,则匹配您添加^
的整个字符串并附加$
,但要使用此技术查找补充内容我需要写^(?!^[0-9]*$).*$
- 据我所知,这种否定的正则表达式的通常连接是可撤销的。
答案 1 :(得分:8)
只需运行正则表达式并逻辑反转输出。所以改变:
if(/foo/)
为:
if(!/foo/)
字符类可以用前导克拉反转:
[A-Z] - > [^ A-Z]
如果你将说明符大写,那么很多特殊字符也会有反转。
\s whitespace
\S non-whitespace
\w word character
\W non-word-character
\d digit
\D non-digit
答案 2 :(得分:6)
需要考虑的几种变体:
匹配由一组特定字符组成的字符串:^[a-z]*$
匹配由除之外的任何字符串组成的字符串:^[^a-z]*$
请注意,有一些快捷方式:
\w
:任何字母数字字符(包括_
),\W
:任何非字母数字字符; \s
:任何空格字符,\S
:任何非空白字符\d
:任何数字,\D
:任何非数字。这可能会变得非常复杂,例如,如果你想......
[\d_\W]
或[^\d_\W]
(即“不是数字,不是_
,不是非字母数字字符”匹配包含子字符串的字符串:^.*substring.*$
匹配不包含子字符串的字符串:^(?:(?!substring).)*$
注意我们必须检查字符串中的每个位置是否存在子串的“不存在”。您还可以将substring
的任何正则表达式替换为匹配包含或不包含某个子正则表达式的字符串。
匹配任何内容:.*
(如果您还要匹配换行符,则必须设置编程语言的相应选项,例如Python中的re.DOTALL
)
如果您不知道如何设置该选项,请匹配任何内容:[\s\S]*
从不匹配任何东西(无论出于何种原因):
$^
(即匹配字符串开头前字符串的结尾),\b\B
(匹配同时存在字边界而非字边界的位置)或(?!)
(匹配一个无法匹配空字符串的位置)。答案 3 :(得分:4)
通过使用否定预测,您将能够处理大多数基本情况
/(?!(OriginalRegex)).*?/
答案 4 :(得分:3)
你的第一个例子毫无意义,但是对于第二个例子你可以使用类字符否定:
[a-z] --> [^a-z]
答案 5 :(得分:1)
我试图理解正则表达式的逆定义。
match(input,regular_expression)= {match1,match2,...,matchN}
反向如何工作?应该是
match(input,inverse_regular_expression)= {imatch1,imatch2,...,imatchN}
如果是这样,第一组结果和第二组之间的关系是什么?如果没有,那么它是什么?