【问题标题】:Combining two regular expressions A and B into C = (A and not B)将两个正则表达式 A 和 B 组合成 C = (A and not B)
【发布时间】:2019-11-27 15:20:38
【问题描述】:

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

  • A 匹配该行并且
  • B 与该行不匹配。

我可以为 AB 的非常简单的情况手动创建 C:比方说 Ax 并且 By,那么 C = ^[^y]*x[^y]*$ 将是一个有效的解决方案。

显然,随着 AB 变得越来越复杂,问题变得越来越困难。有没有一种通用算法可以从 AB 中创建这样的正则表达式 C


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

【问题讨论】:

  • 你可以试试^(?!B)A$,但它确实可能取决于实际的正则表达式:^(?!y)x$
  • 如果 yx 的子字符串,在您的示例中会发生什么?我认为只有当存在不相交的匹配时,您的方法才有效。虽然理论上应该可以进行转换,但我认为用两个不同的模式结合布尔结果(/A/.test(string) and not (/B/.test(string)) in pseudo-syntax)测试一个字符串会更容易。

标签: regex algorithm combinatorics theory


【解决方案1】:

编辑

根据 OP 的初始正则表达式,正如我的答案下方的 cmets 中 @ruakh 所指出的,OP 选择使用 ^(?!.*B).*A。此解决方案匹配 包含 B 的任何字符串,而不是我原来的帖子(如下)所针对的,即最初假设的 匹配 B 的任何字符串后来由 OP 澄清(在我的答案下方的 cmets 中)。


原帖

如果我正确理解您的问题,您正在寻找匹配一个给定模式A,但不匹配模式B 的字符串,这样您的新模式CA 组成和B

简单的正则表达式

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

^(?!B$)A$

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

^(?!y$)x$

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

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

这将匹配xa,但不匹配xx,如here所示


复杂的正则表达式

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

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

示例 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 和不匹配 B 的正确模式。

【讨论】:

  • ^(?!B)A$ 是一个实用的解决方案,但使用的负前瞻模式是正则表达式引擎的匹配规范,lietarlls 所说的超出了理论 CS 的正则表达式语言。此外,前瞻没有指定B 必须匹配整行,而只要求它不匹配任何前缀(因此它可能应该是^(?!B$)A$)。然而,尚不清楚这是否是 OP 想要的(他的示例仅在允许部分匹配时才有意义,而口头描述表明完全匹配。
  • @collapsar 是的,当您将其与更复杂的用例(如预定义模式)结合使用时,负前瞻将失败。它只适用于某些模式,但其他模式会失败(我试图在实践中证明)
  • 模式名称应该不是问题,因为这些是绑定到它们各自正则表达式的变量,需要简单的重新标记 - 还是我在这里遗漏了什么?此外,我不确定预定义模式名称的表达能力,但我怀疑这允许上下文无关语法。
  • This SO answer 确认允许无限长度的环视和递归超出了 TheoCS 的常规语言的概念。递归尤其是一个杀手,因为它允许识别在交集或补集下不接近的 CF 语言。
  • 您的第一个示例应该是^(?!.*B).*A 而不是^(?!B$)A$,对于您的其他各种示例也是如此。 (问题是:“假设 AxBy,那么 C = ^[^y]*x[^y]*$ 将是有效的解决方案。”)
【解决方案2】:

我猜答案很可能是,因为 A、B 和 C 可以是 dependentindependent 表达式,那么结果将属于 combination 类别,其中还包括 permutation 实例,并且会有无数这样的表达式。然后,我非常怀疑是否会有一个通用算法

【讨论】:

  • 怎么回事所有随机单词用粗体写成没有原因
猜你喜欢
  • 2014-09-20
  • 2015-06-12
  • 2021-11-28
  • 1970-01-01
  • 2021-01-10
  • 1970-01-01
  • 2021-07-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多