正则表达式匹配不包含'xxx'的字符串

时间:2010-09-06 09:11:43

标签: regex

我的一个家庭作业问题要求为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)

3 个答案:

答案 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])*$

将匹配任意字符行xyz,只要它不包含字符串xxx

答案 2 :(得分:2)

基本上你已经有了正确的答案 - 干得好。 :)

集合[^abc]中的克拉(^)仅匹配在该集合中找不到字符的位置,因此匹配字符(即字符串)的应用程序是有限且弱的。

正则表达式具有数字量词{n}{a,b},它们允许您匹配模式的定义数量的重复,这将适用于此特定模式(因为它是'x'重复)但它不是特别表达你试图解决的问题(即使是正则表达式!)并且有点脆弱(例如,它不适合负面匹配'xyx'。

一个或一个模式会再次变得冗长而且非常不明显,但它可以作为片段来完成:

(x|xx)[^x] // x OR xx followed by NOT x

显然你可以用迭代算法做到这一点,但与正则表达式相比效率非常低。

尽管在解决方案之外思考已经做得很好。