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

regex以匹配除特定给定字符串之外的任何内容(包括空字符串)

  •  3
  • dreeves  · 技术社区  · 15 年前

    我想测试一个字符串是否包含 "Kansas" 后面除了 " State" .

    实例:

    "I am from Kansas"          true
    "Kansas State is great"     false
    "Kansas is a state"         true
    "Kansas Kansas State"       true
    "Kansas State vs Kansas"    true
    "I'm from Kansas State"     false
    "KansasState"               true
    

    为了 PCRE 我相信答案是:

    'Kansas(?! State)'
    

    但MySQL的regexp似乎不喜欢这样。

    附录:感谢 David M 为了概括这个问题: How to convert a PCRE to a POSIX RE?

    4 回复  |  直到 15 年前
        1
  •  2
  •   Charles    15 年前

    比大型regex更高效(当然,取决于您的数据和引擎的质量)

    WHERE col LIKE '%Kansas%' AND
      (col NOT LIKE '%Kansas State%' OR
      REPLACE(col, 'Kansas State', '') LIKE '%Kansas%')
    

    不过,如果堪萨斯州通常以“堪萨斯州”的形式出现,您可能会发现这一点更好:

    WHERE col LIKE '%Kansas%' AND
      REPLACE(col, 'Kansas State', '') LIKE '%Kansas%'
    

    这还有一个额外的优点,即易于维护。如果堪萨斯州很常见并且文本字段很大,那么它的效果就不太好。当然,您可以在自己的数据上测试它们,并告诉我们它们是如何比较的。

        2
  •  4
  •   dreeves    15 年前

    MySQL没有lookaheads。解决方法是进行两次测试:

    WHERE yourcolumn LIKE '%Kansas%'
      AND yourcolumn NOT LIKE '%Kansas State%'
    

    我用过 LIKE 这里而不是 RLIKE 因为一旦您像这样拆分它,就不再需要正则表达式了。但是,如果由于其他原因仍然需要正则表达式,您仍然可以使用相同的技术。

    请注意,这与您请求的“堪萨斯州”不匹配。

    更新:如果匹配“堪萨斯州”很重要,那么可以使用MySQL支持的丑陋正则表达式:

    'Kansas($|[^ ]| ($|[^S])| S($|[^t])| St($|[^a])| Sta($|[^t])| Stat($|[^e]))'
    

    哎呀:我刚注意到kip已经用一个非常类似的解决方案更新了他的评论。

        3
  •  2
  •   Kip    15 年前

    这应该是可行的,假设在mysql regex中允许前瞻性断言。

    /Kansas(?! State)/
    

    编辑 :好的,这是非常难看的,但是它在Perl中对我有效,并且不使用先行声明:

    /Kansas(([^ ]|$)| (([^S]|$)|S(([^t]|$)|t(([^a]|$)|a(([^t]|$)|t([^e]|$))))))/
    
        4
  •  1
  •   David M    15 年前

    这很难看,但你看:

    您可能不需要将regex一直扩展到最后,这取决于您的输入是否包括“我需要让这个人在堪萨斯州接受手术”之类的内容。

    mysql> select x,x RLIKE 'Kansas($|[^ ]| ($|[^S])| S($|[^t])| St($|[^a])| Sta($|[^t])| Stat($|[^e]))' AS result from examples;
    +------------------------+--------+
    | x                      | result |
    +------------------------+--------+
    | I am from Kansas       |      1 |
    | Kansas State is great  |      0 |
    | Kansas is a state      |      1 |
    | Kansas Kansas State    |      1 |
    | Kansas State vs Kansas |      1 |
    | I'm from Kansas State  |      0 |
    | KansasState            |      1 |
    +------------------------+--------+
    7 rows in set (0.00 sec)