用于验证减法方程式的正则表达式,例如“abc-b=ac”。

16

我遇到了一个正则表达式的问题。

如何验证这样一个“减法方程”?

一个字符串减去另一个字符串等于剩下的部分(所有项都只是普通字符串,不是集合。因此abba是不同的字符串)。

通过

  • abc-b=ac
  • abcde-cd=abe
  • ab-a=b
  • abcde-a=bcde
  • abcde-cde=ab

失败

  • abc-a=c
  • abcde-bd=ace
  • abc-cd=ab
  • abcde-a=cde
  • abc-abc=
  • abc-=abc

以下是我尝试过的正则表达式,你可以尝试修改它

https://regex101.com/r/lTWUCY/1/


1
如果你想解析简单的表达式,那么你可能也想解析复合表达式,比如 abc-(def-ghi)abc-(de-(fg-hi-(ij-kl))),此时正则表达式已经无法胜任这个任务了。你需要一个解析器。 - tripleee
6
我认为这更像是一个探索正则表达式能力和优雅程度的谜题。虽然这个问题可能不太实用,但解决它非常有趣,我也通过解决它学到了很多 :) - Hao Wu
4
如果空白是失败的话,"abc-abc"是什么? - Henry
3
a) 因为 abcde 不包含字符串 bd b) 是的,术语不能被打乱顺序 c) 不,只有三个术语 被减数-减数=差 ,每个术语都不能为空 - Hao Wu
2
@HaoWu:好的,我建议您将这些术语添加到您的问题中。因为现在不清楚它是子字符串减法,还是集合减法。 - smci
显示剩余2条评论
2个回答

17

免责声明:我看到一些评论被删除了。所以让我先说一下,尽管以下答案在代码高尔夫方面很短,但是在涉及的步骤方面并不是最有效率的。不过,考虑到问题的性质和“难题”的方面,它可能表现得还不错。对于一个更有效率的答案,我想将您重定向到答案。


这是我的尝试:

^(.*)(.+)(.*)-\2=(?=.)\1\3$

查看在线演示

  • ^ - 行首锚点。
  • (.*) - 第一组捕获,从 0 个非换行符字符一直到;
  • (.+) - 第二组捕获,从 1 个非换行符字符一直到;
  • (.*) - 第三组捕获,从 0 个非换行符字符一直到;
  • -\2= - 连字符后面跟着对第二组捕获的反向引用和字面上的“=”。
  • (?=.) - 正前瞻断言位置后至少有一个除换行符外的字符。
  • \1\3 - 对第一组和第三组捕获内容的反向引用。
  • $ - 行尾锚点。

编辑:

我想更加严格可能会是:

^([a-z]*)([a-z]+)((?1))-\2=(?=.)\1\3$

13
你可以在正则表达式开头使用一个前瞻捕获组,匹配位于-右侧的文本,即在-=之间的子字符串,并将其捕获在第1组中,以实现更有效率的匹配。然后在正则表达式的主体部分,我们只需检查捕获组#1是否存在,并将文本分别捕获到两个单独的组中,在\1之前和之后。
^(?=[^-]+-([^=]+)=.)([^-]*?)\1([^-]*)-[^=]+=\2\3$

正则表达式示例

正则表达式示例:

  • ^: 开始
  • (?=[^-]+-([^=]+)=.): 前瞻以确保我们有表达式结构pqr-pq=r,更重要的是,在捕获组#1中捕获-=之间的子字符串。在=后面加上.是出于一个原因,以防止在=后面出现任何空字符串。
  • ([^-]*?): 在捕获组#2中匹配0个或多个非-字符
  • \1: 回溯到组#1,以确保我们匹配与捕获组#1中相同的值
  • ([^-]*): 在捕获组#3中匹配0个或多个非-字符
  • -: 匹配一个-
  • [^=]+: 匹配0个或多个非=字符
  • =: 匹配一个=
  • \2\3: 回溯到组#2和#3,它们是相减的差异
  • $: 结尾

1
这真是令人惊叹。但是像 [^-] 这样的限制对于验证可能并不是必要的吗?因为如果 . 失败,[^-] 也会失败...或者这只是为了更好的性能? - Hao Wu
2
实际上,[^-]* 的性能比 .* 要快得多。 - anubhava
2
顺便说一下,这里没有 PCRE,它在 Java、Python、Javascript 等语言中的工作方式也是相同的。 - anubhava
@anubhava 那是 ~PCRE。只是因为这些语言中的正则表达式是按照 Perl 语法制定的。(?=...) 是 Perl 的特色。此外,从数学/ Kleene 视角来看,那不是一个正则表达式。虽然在这里并不重要 :P - Antti Haapala -- Слава Україні
2
你的解决方案让我惊叹不已,我之前没有想到/看到过这种方法,但它真的很聪明++++。 - The fourth bird
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接