有没有办法否定正则表达式?

时间:2013-03-11 11:30:02

标签: regex algorithm regular-language

给出一个描述常规语言的正则表达式 R (没有花哨的反向引用)。是否有一种算法方法来构造正则表达式 R * ,它描述除 R 所描述的那些词之外的所有单词的语言?应该可以Wikipedia说:

  

常规语言在各种操作下关闭,也就是说,如果语言 K L 是常规的,那么以下操作的结果也是如此:[... ]补充¬L

例如,给定字母 {a,b,c} ,语言(abc *)+ 的反转是(a |(ac | b | C)*)

。?

正如DPenner在评论中已经指出的那样,正则表达式的倒数可以比原始表达式指数级大。这使得反转正则表达式不适合实现用于搜索目的的否定部分表达式语法。是否存在保留 O(n * m)运行时特性的算法(其中 n 是正则表达式的大小, m 是长度正则表达式匹配的输入)和允许否定的子表达式?

2 个答案:

答案 0 :(得分:4)

不幸的是,nhahdtdh在评论中给出的答案与我们能做的一样好(到目前为止)。给定的正则表达式是否生成所有字符串是PSPACE-complete。由于NP中的所有问题都在PSPACE完全中,因此普遍性问题的有效解决方案意味着P = NP。

如果您的问题有效解决方案,您能否解决普遍性问题?当然可以。

  1. 使用您的高效算法为否定生成正则表达式;
  2. 确定生成的正则表达式是否生成空集。
  3. 请注意,问题“给定正则表达式,是否生成空集”非常简单:

    1. 正则表达式{}生成空集。
    2. (r + s)生成空集iff rs生成空集。
    3. (rs)生成空集iff rs生成空集。
    4. 没有其他任何东西可以生成空集。
    5. 基本上,很容易判断正则表达式是否生成空集:只需开始计算正则表达式。

      (注意,尽管上述过程在输出长度方面是有效的,但就输入长度而言,如果输出长度比输入长度多于多次,则可能效率不高。但是,如果是在这种情况下,无论如何我们都会得到相同的结果,即你的算法效率不高,因为从给定的输入生成指数级更长的输出需要指数级的许多步骤。)

答案 1 :(得分:1)

维基百科说:... if there exists at least one regex that matches a particular set then there exist an infinite number of such expressions。我们可以从这个陈述中推断出有无数个表达式来描述除R所描述的所有单词的语言。

同样,(同样@nhahtdh试图解释)解决这个问题的最简单算法是将评估范围扩展到正则表达式语言本身的上下文之外。即:使用原始正则表达式匹配要排除的字符串(表示要使用的有限子集),然后将任何匹配失败视为实际匹配(出于无限的其他可能性)。因此,如果匹配结果为负,则候选字符串是有效解决方案的子集。