将两个正则表达式A和B组合成C =(A而不是B)

时间:2019-07-18 16:11:20

标签: regex algorithm combinatorics theory

假设我有一个正则表达式 A 和另一个正则表达式 B 作为输入。我想创建一个新的正则表达式 C ,当且仅当

时,该表达式与一行匹配
  • A 匹配该行,并且
  • B 与该行不匹配。

对于 A B 的非常简单的情况,我能够手动创建 C :假设 A RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ index.php [QSA,L] ,而 B x,则 C = y是有效的解决方案。

显然,随着 A B 变得越来越复杂,问题变得更加棘手。是否有通用算法可从 A B 中创建 C 这样的正则表达式?


注意:从regular languages are closed under intersection and complement开始,理论上应该存在这样的算法。我知道现代IT系统中可用的正则表达式的表达能力超过了正式的正则语言,但是 A B 仅限于功能子集的解决方案可以使用正式语言,但是 C 使用了现代正则表达式引擎的扩展功能,对我来说非常合适。

2 个答案:

答案 0 :(得分:3)

编辑

基于OP的初始正则表达式,并由@ruakh在我的回答下方的注释中指出,OP选择使用^(?!.*B).*A。此解决方案匹配包含 B的所有字符串,而不是我的原始帖子(如下)所针对的字符串,即匹配 B的任何字符串最初由OP承担,后来(在我的回答下方的评论中)得到澄清。


原始帖子

如果我正确理解了您的问题,则说明您要匹配的字符串匹配一个给定的模式A,但不匹配模式B,这样您的新模式C为由AB组成。

简单的正则表达式

鉴于模式Ax,模式By,新的正则表达式模式C应如下所示:

^(?!B$)A$

或您提供的示例正则表达式:

^(?!y$)x$

也许是一个更好的例子来说明这一点:

  • A模式:x.
  • B模式:xx
  • C变为:^(?!xx$)x.$

这将与here匹配xa但不匹配xx


复杂的正则表达式

关于更复杂的正则表达式,它可能完全取决于模式和所使用的正则表达式引擎。正则表达式可能会超时,如果使用递归,控制动词,模式修饰符等,它可能会完全中断。

更好的选择是使用代码独立评估两个正则表达式以确定结果。

示例1

在此示例中,假设两个模式都使用相同的预定义模式名称,则正则表达式会中断:

  • A(?(DEFINE)(?<t>x))(?&t).
  • B(?(DEFINE)(?<t>x))(?&t){2}
  • C^(?!(?(DEFINE)(?<t>x))(?&t){2}$)(?(DEFINE)(?<t>x))(?&t).$

它失败,如图here

示例2

这是一个递归示例,无法正常工作:

  • Aa(?R)z
  • Baz
  • ^(?!az$)a(?R)?z$

它失败,如图here


当然,这是假设C^(?!B$)A$的初始假设是用于A的匹配和B的不匹配的正确模式。

答案 1 :(得分:0)

我猜测答案很可能,因为A,B和C可以依赖独立表达式,然后结果将属于 combination 类别,其中还包括 permutation 实例,并且此类表达式的数量将是无限的。然后,我非常怀疑是否会有一个泛型算法