用于匹配前向引用练习的正则表达式

3

我正在做一个关于正则表达式前向引用的练习,就像这里所问的那样。

任务如下:

  • 字符串stictac组成
  • tic不能是其自身的直接相邻字符
  • 第一个tic只能在tac出现至少两次之后才能出现

我已经使用了这个regex来解决它。但它没有使用forward reference,所以我真的想知道如何使用它来解决这个问题。

^tac(tac)+(tic(tac)+){0,}(tic)?$

有效:

tactactic
tactactictactic

无效:

tactactictactictictac
tactictac

我该怎么解决这个问题?


1
你自己的正则表达式无法匹配以超过两个“tac”开头的字符串,例如“tactactactic”。你已经得到了答案,但是为了性能考虑,你应该选择一个更轻量级的正则表达式:“^(tac)(\1+tic)+\1*$”。 - revo
1
@revo 这也是一个很好的解决方案,为什么不发表呢? - The fourth bird
2
@Thefourthbird 我觉得它没有回答问题,因为OP明确要求涉及前向引用的解决方案已经给出。 - revo
1
@revo 你说得对,我猜这个练习没有足够的案例。而且你的方法也很好用。 - user11447782
3个回答

1

这里使用了前向引用:

^(\2tic|(tac))+$

演示

实际上,它与此页面上给出的示例非常相似。


谢谢。我一直在尝试如何使用“前向引用”来解决问题,现在找到了解决方法。 - user11447782

0
如果字符串中至少应该有2个“tic”,您可以使用负向先行断言来断言不存在“tictic”,并从匹配至少2次“tic”开始。
^(?!.*tictic)(?:tac){2}tic(?:t[ai]c)*$

正则表达式演示

如果字符串也可以仅由一个或多个时间标记组成,则可以使用交替:

^(?:(?:tac)+|(?!.*(tictic))(?:tac){2,}tic(?:t[ia]c)*)$
  • ^ 字符串的开始
  • (?: 非捕获组
    • (?:tac)+ 仅重复1次以上tac
    • |
    • (?!.*(tictic)) 断言右侧不包含tactac
    • (?:tac){2,}(?:t[ia]c)* 重复2次以上tac,后跟tic并重复0次或多次的tic或tac直到字符串结束
  • ) 关闭非捕获组
  • $ 字符串的结束

正则表达式演示


我不太明白“tempered greedy token”的部分,但您能否展示一个涉及“forward reference”的例子呢?谢谢。 - user11447782

0

这个简单的正则表达式应该足够好,无需使用任何前后查找或温和贪婪标记,因为它们在匹配方面相当昂贵。

^tac(tac(?:tic)?)+$

解释:

  • ^tac - 以 tac 开始的字符串
  • (tac(?:tic)?)+ - 这匹配了 tac,后面可以选择性地跟着 tic,因此不会出现两个 tic 相邻的情况。由于这里 tic 是可选的,因此它允许匹配任意次数的 tac 以匹配模式。
  • $ - 字符串结束

正则表达式演示


“tactactactictactic” 应该是有效的吧? - Keith
你们俩都是对的。两个模式都被照顾到了。请检查。 - Pushpesh Kumar Rajwanshi
谢谢您的回答,但您能否也考虑“前向引用”(但不是冗余的方式)? - user11447782
@ greeny1234:很抱歉,我不确定您所说的“forward reference”是什么意思。您是指正向先行断言吗? - Pushpesh Kumar Rajwanshi
我已经在问题中放置了一个链接。 - user11447782
好的,让我检查一下。 - Pushpesh Kumar Rajwanshi

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