假设我有一个正则表达式 A 和另一个正则表达式 B 作为输入。我想创建一个新的正则表达式 C ,当且仅当
时,该表达式与一行匹配对于 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 使用了现代正则表达式引擎的扩展功能,对我来说非常合适。
答案 0 :(得分:3)
基于OP的初始正则表达式,并由@ruakh在我的回答下方的注释中指出,OP选择使用^(?!.*B).*A
。此解决方案匹配包含 B
的所有字符串,而不是我的原始帖子(如下)所针对的字符串,即匹配 B
的任何字符串最初由OP承担,后来(在我的回答下方的评论中)得到澄清。
如果我正确理解了您的问题,则说明您要匹配的字符串匹配一个给定的模式A
,但不匹配模式B
,这样您的新模式C
为由A
和B
组成。
鉴于模式A
为x
,模式B
为y
,新的正则表达式模式C
应如下所示:
^(?!B$)A$
或您提供的示例正则表达式:
^(?!y$)x$
也许是一个更好的例子来说明这一点:
A
模式:x.
B
模式:xx
C
变为:^(?!xx$)x.$
这将与here匹配xa
但不匹配xx
关于更复杂的正则表达式,它可能完全取决于模式和所使用的正则表达式引擎。正则表达式可能会超时,如果使用递归,控制动词,模式修饰符等,它可能会完全中断。
更好的选择是使用代码独立评估两个正则表达式以确定结果。
在此示例中,假设两个模式都使用相同的预定义模式名称,则正则表达式会中断:
A
:(?(DEFINE)(?<t>x))(?&t).
B
:(?(DEFINE)(?<t>x))(?&t){2}
C
:^(?!(?(DEFINE)(?<t>x))(?&t){2}$)(?(DEFINE)(?<t>x))(?&t).$
它失败,如图here
这是一个递归示例,无法正常工作:
A
:a(?R)z
B
:az
^(?!az$)a(?R)?z$
它失败,如图here
当然,这是假设C
:^(?!B$)A$
的初始假设是用于A
的匹配和B
的不匹配的正确模式。
答案 1 :(得分:0)
我猜测答案很可能否,因为A,B和C可以依赖和独立表达式,然后结果将属于 combination 类别,其中还包括 permutation 实例,并且此类表达式的数量将是无限的。然后,我非常怀疑是否会有一个泛型算法。