regex 包含重复字符的正则表达式

u3r8eeie  于 2023-05-08  发布在  其他
关注(0)|答案(4)|浏览(125)

我需要编写一个正则表达式,它可以检测只包含字符x、y和z的字符串,但其中的字符与相邻字符不同。
这里有一个例子
xyzxzyz =通过
xyxyxyx =通过
xxyzxz =未通过(重复x次)
zzzxxzz =失败(相邻字符重复)
我以为这会奏效((x| y| z)?)*,但它似乎不起作用。有什么建议吗?

编辑

请注意,我正在寻找一个答案,不允许向前看或向后看操作。唯一允许的操作是交替、串联、分组和闭合

chy5wohz

chy5wohz1#

通常对于这种类型的问题,如果正则表达式不够简单,无法直接导出,您可以从绘制DFA开始,并从中导出正则表达式。
您应该能够导出以下DFA。q1、q2、q3、q4是结束状态,其中q1也是开始状态。q5是失败/陷阱状态。

有几种方法可以找到DFA的正则表达式。我将使用Brzozowski代数方法,如this paper的第5节所述:
对于每个状态qi,等式Ri是项的并集:对于从qi到qj的转变a,项是aRj。基本上,您将查看一个状态的所有传出边。如果Ri是最终状态,则λ也是项之一。
让我引用论文定义部分的恒等式,因为它们在后面会派上用场(λ是空串,是空集):

(ab)c = a(bc) = abc
λx = xλ = x
∅x = x∅ = ∅
∅ + x = x
λ + x* = x*
(λ + x)* = x*

因为q5是一个陷阱态,所以这个公式将以无限递归结束,所以你可以把它放在方程中。它最终将成为空集,如果你把它包含在方程中,它就会消失(在附录中解释)。
您将得出:

R1 = xR2 + yR3 + zR4 + λ
R2 =     + yR3 + zR4 + λ
R3 = xR2 +     + zR4 + λ
R4 = xR2 + yR3       + λ

用替换和Arden定理求解上面的方程,该定理指出:
给定一个形式为X = AX + B的方程,其中λ A,该方程的解为X = A*B
你会找到答案的。
我没有时间和信心来推导整个过程,但我将展示推导的前几个步骤。
通过替换去除R4,注意,由于恒等式,zλ变为z:

R1 = xR2 + yR3 + (zxR2 + zyR3 + z) + λ
R2 =     + yR3 + (zxR2 + zyR3 + z) + λ
R3 = xR2 +     + (zxR2 + zyR3 + z) + λ

重新组合它们:

R1 = (x + zx)R2 + (y + zy)R3 + z + λ
R2 =       zxR2 + (y + zy)R3 + z + λ
R3 = (x + zx)R2 +       zyR3 + z + λ

将Arden定理应用于R3:

R3 = (zy)*((x + zx)R2 + z + λ)
   = (zy)*(x + zx)R2 + (zy)*z + (zy)*

您可以将R3替换回R2和R1并删除R3。我把剩下的作为练习。继续往前走,你应该会找到答案。

附录

我们将解释为什么陷阱态可以从方程中删除,因为它们无论如何都会消失。让我们在这里使用DFA中的状态q5作为示例。

R5 = (x + y + z)R5

使用标识∅ + x = x

R5 = (x + y + z)R5 + ∅

将Arden定理应用于R5:

R5 = (x + y + z)*∅

使用标识∅x = x∅ = ∅

R5 = ∅

恒等式∅x = x∅ = ∅也会在R5代入其他方程时生效,导致R5项消失。

r7xajy2e

r7xajy2e2#

这应该可以实现您想要的功能:

^(?!.*(.)\1)[xyz]*$

(显然,仅适用于具有前瞻功能的引擎)
内容本身由第二部分处理:[xyz]*(任意数量的x、y或z字符)。锚^...$在这里是说它必须是整个字符串。而特殊条件(没有相邻对)由负先行(?!.*(.)\1)处理,它表示字符串中任何地方都不能有一个字符后跟相同的字符。

rlcwz9us

rlcwz9us3#

我有一个想法,而我今天走,并把它放在正则表达式,我还没有找到一个模式,它不匹配正确。下面是正则表达式:

^((y|z)|((yz)*y?|(zy)*z?))?(xy|xz|(xyz(yz|yx|yxz)*y?)|(xzy(zy|zx|zxy)*z?))*x?$

这里有一个fiddle去与它!
如果你发现一个模式不匹配告诉我,我会尝试修改它!我知道有点晚了,但我真的很烦恼,我不能解决它。

gojuced7

gojuced74#

我知道这是一个很老的问题,也有一个批准的解决方案。但是,对于同样的情况,如果你想检查包含连续字符的正则表达式,我将发布一个更可能和快速的解决方案。
使用下面的正则表达式:

String regex = "\\b\\w*(\\w)\\1\\1\\w*";

列出上述表达式返回结果的可能情况。

用例1:abcddddd或123444

结果:匹配

例2:abcd或1234

结果:不匹配

情况3:&*%$$$(特殊字符)

结果:不匹配
希望这对你有帮助…Thanks:)

相关问题