将两个正则表达式 A 和 B 组合成 C = (A and not B)
Combining two regular expressions A and B into C = (A and not B)
假设我有一个正则表达式 A 和另一个正则表达式 B 作为输入。我想创建一个新的正则表达式 C 匹配一行当且仅当
- A匹配行和
- B不匹配行
我可以为 A 和 B 的非常简单的情况手动创建 C : 假设 A 是 x
而 B 是 y
,那么 C = ^[^y]*x[^y]*$
将是一个有效的解决方案。
显然,随着 A 和 B 变得更加复杂,问题变得更加困难。是否存在用于从 A 和 B 中创建这样的正则表达式 C 的通用算法?
注:由于regular languages are closed under intersection and complement,理论上应该存在这样的算法。我知道现代 IT 系统中可用的正则表达式的表达能力超过了正式的正则语言,但是 A 和 B 的解决方案是仅限于形式语言可用的功能子集,但 C 使用现代正则表达式引擎的扩展功能,对我来说非常好。
编辑
根据 OP 的初始正则表达式,正如 @ruakh 在我的回答下方的评论中指出的那样,OP 选择使用 ^(?!.*B).*A
。此解决方案匹配 包含 B
的任何字符串,而不是我最初的 post(下方)目标,即 匹配的任何字符串 B
正如最初假设的那样,后来由 OP 澄清(在我的回答下方的评论中)。
原版Post
如果我对你的问题的理解正确,你正在寻找匹配一个字符串,该字符串匹配一个给定的模式 A
,但不匹配模式 B
,这样你的新模式 C
由 A
和 B
.
组成
简单的正则表达式
鉴于模式 A
是 x
并且模式 B
是 y
,新的正则表达式模式 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
这是一个无法正常工作的递归示例:
A
: a(?R)z
B
: az
^(?!az$)a(?R)?z$
如图所示失败here
当然,这假设初始假设 C
: ^(?!B$)A$
是用于匹配 A
和 non-matching 的正确模式 B
.
我猜答案很可能是 否 因为 A、B 和 C 可以 依赖 和 independent 表达式,那么结果将属于 combination 类别,其中还包括 permutation 实例,并且会有一个无数这样的表达。然后,我非常怀疑是否会有一种 通用算法 。
假设我有一个正则表达式 A 和另一个正则表达式 B 作为输入。我想创建一个新的正则表达式 C 匹配一行当且仅当
- A匹配行和
- B不匹配行
我可以为 A 和 B 的非常简单的情况手动创建 C : 假设 A 是 x
而 B 是 y
,那么 C = ^[^y]*x[^y]*$
将是一个有效的解决方案。
显然,随着 A 和 B 变得更加复杂,问题变得更加困难。是否存在用于从 A 和 B 中创建这样的正则表达式 C 的通用算法?
注:由于regular languages are closed under intersection and complement,理论上应该存在这样的算法。我知道现代 IT 系统中可用的正则表达式的表达能力超过了正式的正则语言,但是 A 和 B 的解决方案是仅限于形式语言可用的功能子集,但 C 使用现代正则表达式引擎的扩展功能,对我来说非常好。
编辑
根据 OP 的初始正则表达式,正如 @ruakh 在我的回答下方的评论中指出的那样,OP 选择使用 ^(?!.*B).*A
。此解决方案匹配 包含 B
的任何字符串,而不是我最初的 post(下方)目标,即 匹配的任何字符串 B
正如最初假设的那样,后来由 OP 澄清(在我的回答下方的评论中)。
原版Post
如果我对你的问题的理解正确,你正在寻找匹配一个字符串,该字符串匹配一个给定的模式 A
,但不匹配模式 B
,这样你的新模式 C
由 A
和 B
.
简单的正则表达式
鉴于模式 A
是 x
并且模式 B
是 y
,新的正则表达式模式 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
这是一个无法正常工作的递归示例:
A
:a(?R)z
B
:az
^(?!az$)a(?R)?z$
如图所示失败here
当然,这假设初始假设 C
: ^(?!B$)A$
是用于匹配 A
和 non-matching 的正确模式 B
.
我猜答案很可能是 否 因为 A、B 和 C 可以 依赖 和 independent 表达式,那么结果将属于 combination 类别,其中还包括 permutation 实例,并且会有一个无数这样的表达。然后,我非常怀疑是否会有一种 通用算法 。