代码之家  ›  专栏  ›  技术社区  ›  ubiquibacon

与不包含“xxx”的字符串匹配的regex

  •  3
  • ubiquibacon  · 技术社区  · 14 年前

    我的一个家庭作业问题是为所有字符串开发一个regex x,y,z 不包含 xxx

    在读了一些书之后,我发现了一些负面的展望,并使这一点非常有效:

    (x(?!xx)|y|z)*

    尽管如此,本着完备性的精神,有没有必要在没有负面展望的情况下写下这篇文章呢?

    我读过的书让我觉得可以结合 carets (^) 但是我不能得到正确的组合,所以我不确定。

    更进一步,是否可以排除类似 XXX 仅使用 or (|) 运算符,但仍以递归方式检查字符串?

    编辑9/6/2010:

    我想我回答了我自己的问题。我还搞得一团糟,只想用 (·) 我很确定我知道了…它并不像我想象的那么凌乱。如果有人有时间用人眼来验证这一点,我会感激的。

    (xxy|xxz|xy|xz|y|z)*(xxy|xxz|xx|xy|xz|x|y|z)

    3 回复  |  直到 14 年前
        1
  •  5
  •   Kobi    14 年前

    试试这个:

    ^(x{0,2}(y|z|$))*$
    

    基本思想是:对于最多2个x的匹配,后跟另一个字母或字符串的结尾。

    当到达一个有3个x的点时,regex没有允许它保持匹配的规则,它失败了。

    工作示例: 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
    )*$
    

    根据最新的编辑,这里有一个更平坦的模式版本:我不完全确定我是否理解你对管道的迷恋,但你可以消除更多的选择-通过允许第二组的空匹配,你不需要从第一组重复排列。这个regex还允许__,我认为它包含在您的语言中。

    ^(xxy|xxz|xy|xz|y|z)*(xx|x|)$
    
        2
  •  2
  •   annakata    14 年前

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

    一套克拉(^) [^abc] 只有在集合中找不到字符时才会匹配,因此用于匹配字符顺序(即字符串)的应用程序是有限的和弱的。

    regex有数字量词 {n} {a,b} 它允许您匹配一个模式的定义数量的表示,这对于这个特定的模式是有效的(因为它是“x”重复的),但是它并不能具体地表达您试图解决的问题(甚至对于regex!)并且有点脆弱(例如,它不适合负匹配“xyx”。

    一个或模式将是冗长的,相当不可表达,但它可以作为片段:

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

    显然,您可以使用迭代算法来实现这一点,但是与regex相比,这是非常低效的。

    不过,做得很好,因为思考超出了解决方案。

        3
  •  2
  •   Tim Pietzcker    14 年前

    我知道你不想使用lookahead,但有另一种方法可以解决这个问题:

    ^(?:(?!xxx)[xyz])*$
    

    将匹配任何字符行 x , y z 只要它不包含字符串 xxx .