我的一个家庭作业问题要求为x,y,z
以上的所有字符串开发一个不包含xxx
在做了一些阅读之后,我发现了一个消极的前瞻,并使这个很有效:
(x(?!xx)|y|z)*
仍然,本着完整的精神,无论如何都要写下这个没有消极的前瞻?
我已经完成的阅读让我觉得可以使用carets
(^)
的某种组合来完成,但我无法得到正确的组合,所以我不确定。
更进一步,是否可以仅使用xxx
or
运算符排除(|)
之类的字符串,但仍然以递归方式检查字符串?
编辑9/6/2010:
想想我回答了自己的问题。我更多地搞砸了这个,尝试只用or
(|)
语句来制作这个正则表达式,我很确定我已经弄明白了...它并不像我想象的那样混乱。如果其他人有时间用肉眼验证这一点我会很感激。
(xxy|xxz|xy|xz|y|z)*(xxy|xxz|xx|xy|xz|x|y|z)
答案 0 :(得分:5)
试试这个:
^(x{0,2}(y|z|$))*$
基本思路是:匹配最多2个X,然后是另一个字母或字符串的结尾。
当你到达有3个X的点时,正则表达式没有允许它保持匹配的规则,并且它失败了。
工作示例:http://rubular.com/r/ePH0fHlZxL
写一样的不太紧凑的方法是(带有空格,通常是/x
标志):
^(
y| # y is ok
z| # so is z
x(y|z|$)| # a single x, not followed by x
xx(y|z|$) # 2 x's, not followed by x
)*$
基于最新的编辑,这里是一个更平坦的模式版本:我不完全确定我理解你对管道的迷恋,但你可以消除一些更多的选择 - 通过在第二组上允许空匹配你不需要重复第一组的排列。那个正则表达式也允许ε,我认为它包含在你的语言中。
^(xxy|xxz|xy|xz|y|z)*(xx|x|)$
答案 1 :(得分:2)
我知道你不想使用前瞻,但这是解决这个问题的另一种方法:
^(?:(?!xxx)[xyz])*$
将匹配任意字符行x
,y
或z
,只要它不包含字符串xxx
。
答案 2 :(得分:2)
基本上你已经有了正确的答案 - 干得好。 :)
集合[^abc]
中的克拉(^)仅匹配在该集合中找不到字符的位置,因此匹配字符(即字符串)的应用程序是有限且弱的。
正则表达式具有数字量词{n}
和{a,b}
,它们允许您匹配模式的定义数量的重复,这将适用于此特定模式(因为它是'x'重复)但它不是特别表达你试图解决的问题(即使是正则表达式!)并且有点脆弱(例如,它不适合负面匹配'xyx'。
一个或一个模式会再次变得冗长而且非常不明显,但它可以作为片段来完成:
(x|xx)[^x] // x OR xx followed by NOT x
显然你可以用迭代算法做到这一点,但与正则表达式相比效率非常低。
尽管在解决方案之外思考已经做得很好。