【问题标题】:Regular expression that doesn't contain certain string [duplicate]不包含特定字符串的正则表达式[重复]
【发布时间】:2010-10-17 14:06:32
【问题描述】:

我有这样的事情

aabbabcaabda

用于选择由 a 包裹的最小组,我有这个 /a([^a]*)a/,它工作得很好

但是我对 aa 包裹的组有疑问,我需要类似的东西 /aa([^aa]*)aa/ 不起作用,我不能像/aa([^a]*)aa/ 那样使用第一个,因为它会在第一次出现 a 时结束,这是我不想要的。

一般来说,有什么办法,怎么说不包含字符串 我可以用[^a]不包含字符

简单地说,我需要 aa 后跟除序列 aa 之外的任何字符,然后以 aa

【问题讨论】:

  • @SteveChambers 你确实意识到这个问题已经超过 7 年了并且已经有一个公认的答案了吗?
  • 当然可以,但据我了解,这两点都不是不应链接到副本的原因。

标签: regex regex-negation


【解决方案1】:

通过谷歌的力量,我找到了a blogpost from 2007,它给出了以下匹配字符串的正则表达式,包含某个子字符串:

^((?!my string).)*$

它的工作原理如下:它会查找零个或多个 (*) 字符 (.),这些字符 (.) 不以您的字符串开头(?! - 负前瞻),并规定整个字符串必须由这些字符组成(由使用 ^ 和 $ 锚)。或者换一种说法:

整个字符串必须由不以给定字符串开头的字符组成,这意味着该字符串不包含给定的子字符串。

【讨论】:

  • 根据文档,这是消极的前瞻,而不是后瞻
  • (来自引用的博客)完整的正则表达式参考:regular-expressions.info/refadv.html
  • 该问题的确切解决方案是:^aa(?!.*aa.*aa).*aa$ 即从 aa 开始,向前看并丢弃后面的选择 [anything]aa[anything]aa ,并以 aa 结束
  • 代替句点,您可以匹配单行后的内容,如下所示:^((?!my string)(\s|\S))*$
  • 我想这取决于引擎?根据MDN,点不识别Javascript 中的行终止符。 SublimeText 的“查找/替换”正则表达式也不匹配带点的换行符。
【解决方案2】:

一般来说,编写一个 not 包含特定字符串的正则表达式是很痛苦的。我们必须为计算模型执行此操作 - 您采用 NFA,它很容易定义,然后将其简化为正则表达式。不包含“猫”的事物的表达式大约有 80 个字符长。

编辑:我刚刚完成,是的,它是:

aa([^a] | a[^a])aa

Here 是一个非常简短的教程。我以前发现了一些很棒的,但我再也看不到了。

【讨论】:

【解决方案3】:

你只需要一个不情愿的量词:

regex: /aa.*?aa/

aabbabcaabda   => aabbabcaa

aaaaaabda      => aaaa

aabbabcaabda   => aabbabcaa

aababaaaabdaa  => aababaa, aabdaa

您也可以使用否定前瞻,但在这种情况下,它只是完成相同事情的一种更冗长的方式。此外,它比 gpojd 看起来要复杂一些。在允许点使用下一个字符之前,必须在每个位置应用前瞻。

/aa(?:(?!aa).)*aa/

至于 Claudiu 和 finnw 建议的方法,当哨兵字符串只有两个字符长时,它可以正常工作,但是(正如 Claudiu 承认的)对于较长的字符串来说太笨拙了。

【讨论】:

  • 我认为我们的方式是唯一适用于非回溯实现 (swtch.com/~rsc/regexp/regexp1.html) 的方法,但是是的,它非常烦人。我只是不太了解正则表达式,无法了解这些前瞻性的东西=)。
  • 大多数现代正则表达式风格,尤其是那些内置在编程语言中的风格,都是回溯的 NFA 类型。甚至 JavaScript,一种功能最少的风格,也支持前瞻和不情愿的量词。 regular-expressions.info/refflavors.html
【解决方案4】:
/aa([^a]|a[^a])*aa/

【讨论】:

    【解决方案5】:

    我不确定它是否是标准构造,但我认为您应该看看“负前瞻”(它写成:“?!”,不带引号)。 这比该线程中的所有答案(包括已接受的答案)要容易得多。

    示例: 正则表达式:“^(?!123)[0-9]*\w” 捕获任何以数字开头的字符串,后跟字母,除非“这些数字”是 123。

    http://msdn.microsoft.com/en-us/library/az24scfc%28v=vs.110%29.aspx#grouping_constructs (微软页面,但相当全面)用于前瞻/后视

    PS:它对我很有效(.Net)。但是,如果我在某些方面有误,请告诉我们。我发现这个结构非常简单有效,所以我对接受的答案感到惊讶。

    【讨论】:

      【解决方案6】:

      我必须替换以下代码,将 GET 参数添加到对 JS 文件的所有引用,除了一个。

      <link rel="stylesheet" type="text/css" href="/login/css/ABC.css" />
      <script type="text/javascript" language="javascript" src="/localization/DEF.js"></script>
      <script type="text/javascript" language="javascript" src="/login/jslib/GHI.js"></script>
      <script type="text/javascript" language="javascript" src="/login/jslib/md5.js"></script>
      sendRequest('/application/srvc/EXCEPTION.js', handleChallengeResponse, null);
      sendRequest('/application/srvc/EXCEPTION.js",handleChallengeResponse, null);
      

      这是使用的匹配器:

      (?<!EXCEPTION)(\.js)
      

      这样做是查找所有出现的“.js”,如果它们之前有“EXCEPTION”字符串,则从结果数组中丢弃该结果。这就是所谓的消极回顾。由于我花了一天的时间来了解如何做到这一点,所以我想我应该分享一下。

      【讨论】:

        【解决方案7】:
        ".*[^(\\.inc)]\\.ftl$"
        

        在 Java 中,这将找到所有以“.ftl”结尾但不以“.inc.ftl”结尾的文件,这正是我想要的。

        【讨论】:

        • []inc 拆分为inc。所以"a.i.ftl".matches(".*[^(\\.inc)]\\.ftl$")"a.inc.ftl".matches(".*[^(\\.inc)]\\.ftl$") 都是错误的。
        猜你喜欢
        • 2015-04-10
        • 1970-01-01
        • 1970-01-01
        • 2017-10-02
        • 2020-04-22
        • 1970-01-01
        • 2020-08-25
        • 2019-10-07
        • 2011-07-22
        相关资源
        最近更新 更多