我需要编写一个正则表达式,它可以检测只包含字符x、y和z的字符串,但其中的字符与相邻字符不同。这里有一个例子xyzxzyz =通过xyxyxyx =通过xxyzxz =未通过(重复x次)zzzxxzz =失败(相邻字符重复)我以为这会奏效((x| y| z)?)*,但它似乎不起作用。有什么建议吗?
编辑
请注意,我正在寻找一个答案,不允许向前看或向后看操作。唯一允许的操作是交替、串联、分组和闭合
chy5wohz1#
通常对于这种类型的问题,如果正则表达式不够简单,无法直接导出,您可以从绘制DFA开始,并从中导出正则表达式。您应该能够导出以下DFA。q1、q2、q3、q4是结束状态,其中q1也是开始状态。q5是失败/陷阱状态。
有几种方法可以找到DFA的正则表达式。我将使用Brzozowski代数方法,如this paper的第5节所述:对于每个状态qi,等式Ri是项的并集:对于从qi到qj的转变a,项是aRj。基本上,您将查看一个状态的所有传出边。如果Ri是最终状态,则λ也是项之一。让我引用论文定义部分的恒等式,因为它们在后面会派上用场(λ是空串,是空集):
a
(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:
X = AX + B
X = A*B
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:
∅ + x = x
R5 = (x + y + z)R5 + ∅
将Arden定理应用于R5:
R5 = (x + y + z)*∅
使用标识∅x = x∅ = ∅:
∅x = x∅ = ∅
R5 = ∅
恒等式∅x = x∅ = ∅也会在R5代入其他方程时生效,导致R5项消失。
r7xajy2e2#
这应该可以实现您想要的功能:
^(?!.*(.)\1)[xyz]*$
(显然,仅适用于具有前瞻功能的引擎)内容本身由第二部分处理:[xyz]*(任意数量的x、y或z字符)。锚^...$在这里是说它必须是整个字符串。而特殊条件(没有相邻对)由负先行(?!.*(.)\1)处理,它表示字符串中任何地方都不能有一个字符后跟相同的字符。
[xyz]*
^...$
(?!.*(.)\1)
rlcwz9us3#
我有一个想法,而我今天走,并把它放在正则表达式,我还没有找到一个模式,它不匹配正确。下面是正则表达式:
^((y|z)|((yz)*y?|(zy)*z?))?(xy|xz|(xyz(yz|yx|yxz)*y?)|(xzy(zy|zx|zxy)*z?))*x?$
这里有一个fiddle去与它!如果你发现一个模式不匹配告诉我,我会尝试修改它!我知道有点晚了,但我真的很烦恼,我不能解决它。
gojuced74#
我知道这是一个很老的问题,也有一个批准的解决方案。但是,对于同样的情况,如果你想检查包含连续字符的正则表达式,我将发布一个更可能和快速的解决方案。使用下面的正则表达式:
String regex = "\\b\\w*(\\w)\\1\\1\\w*";
列出上述表达式返回结果的可能情况。
用例1:abcddddd或123444
结果:匹配
例2:abcd或1234
结果:不匹配
情况3:&*%$$$(特殊字符)
结果:不匹配希望这对你有帮助…Thanks:)
4条答案
按热度按时间chy5wohz1#
通常对于这种类型的问题,如果正则表达式不够简单,无法直接导出,您可以从绘制DFA开始,并从中导出正则表达式。
您应该能够导出以下DFA。q1、q2、q3、q4是结束状态,其中q1也是开始状态。q5是失败/陷阱状态。
有几种方法可以找到DFA的正则表达式。我将使用Brzozowski代数方法,如this paper的第5节所述:
对于每个状态qi,等式Ri是项的并集:对于从qi到qj的转变
a
,项是aRj。基本上,您将查看一个状态的所有传出边。如果Ri是最终状态,则λ也是项之一。让我引用论文定义部分的恒等式,因为它们在后面会派上用场(λ是空串,是空集):
因为q5是一个陷阱态,所以这个公式将以无限递归结束,所以你可以把它放在方程中。它最终将成为空集,如果你把它包含在方程中,它就会消失(在附录中解释)。
您将得出:
用替换和Arden定理求解上面的方程,该定理指出:
给定一个形式为
X = AX + B
的方程,其中λ A,该方程的解为X = A*B
。你会找到答案的。
我没有时间和信心来推导整个过程,但我将展示推导的前几个步骤。
通过替换去除R4,注意,由于恒等式,zλ变为z:
重新组合它们:
将Arden定理应用于R3:
您可以将R3替换回R2和R1并删除R3。我把剩下的作为练习。继续往前走,你应该会找到答案。
附录
我们将解释为什么陷阱态可以从方程中删除,因为它们无论如何都会消失。让我们在这里使用DFA中的状态q5作为示例。
使用标识
∅ + x = x
:将Arden定理应用于R5:
使用标识
∅x = x∅ = ∅
:恒等式
∅x = x∅ = ∅
也会在R5代入其他方程时生效,导致R5项消失。r7xajy2e2#
这应该可以实现您想要的功能:
(显然,仅适用于具有前瞻功能的引擎)
内容本身由第二部分处理:
[xyz]*
(任意数量的x、y或z字符)。锚^...$
在这里是说它必须是整个字符串。而特殊条件(没有相邻对)由负先行(?!.*(.)\1)
处理,它表示字符串中任何地方都不能有一个字符后跟相同的字符。rlcwz9us3#
我有一个想法,而我今天走,并把它放在正则表达式,我还没有找到一个模式,它不匹配正确。下面是正则表达式:
这里有一个fiddle去与它!
如果你发现一个模式不匹配告诉我,我会尝试修改它!我知道有点晚了,但我真的很烦恼,我不能解决它。
gojuced74#
我知道这是一个很老的问题,也有一个批准的解决方案。但是,对于同样的情况,如果你想检查包含连续字符的正则表达式,我将发布一个更可能和快速的解决方案。
使用下面的正则表达式:
列出上述表达式返回结果的可能情况。
用例1:abcddddd或123444
结果:匹配
例2:abcd或1234
结果:不匹配
情况3:&*%$$$(特殊字符)
结果:不匹配
希望这对你有帮助…Thanks:)