【问题标题】:Regex for all strings not containing a string? [duplicate]所有不包含字符串的字符串的正则表达式? [复制]
【发布时间】:2010-12-30 14:44:32
【问题描述】:

好的,这是完全愚蠢的事情,但这是我从来没有学会做的事情,而且很麻烦。

如何指定不包含其他字符序列的字符串。例如,我想匹配所有不以 '.config' 结尾的行

我认为我可以做到

.*[^(\.config)]$

但这不起作用(为什么不呢?)

我知道我能做到

.*[^\.][^c][^o][^n][^f][^i][^g]$

但是请告诉我有更好的方法

【问题讨论】:

  • 您使用的是什么正则表达式引擎?他们可以非常支持的功能。你应该用你正在使用的引擎标记你的问题。
  • 为什么不使用grep -v "\.config"
  • @Lazer - 因为世界上并非所有东西都是 *nix 系统?
  • 或者他们是重复的!!!!???
  • 这是副本。另一个问题是在Jan 2 '09 at 7:30 上提出的(并成为社区),你的问题是在Dec 28 '09 at 21:47 上提出的(差不多一年后)。我正在标记这个问题。

标签: regex


【解决方案1】:

您可以使用negative lookbehind,例如:

.*(?<!\.config)$

这匹配除了以“.config”结尾的所有字符串

【讨论】:

  • 这行得通,但 .*(?!=\.config)$ 不行——我认为这两种语法是等价的。有什么线索吗?
  • 它们不等价。 (?
  • 不,他们不是。负前瞻是(?!matchthis),您的示例无法运行,因为您在已经位于字符串末尾 ($) 的时刻正在前瞻。
  • 实际上,该链接夸大了难度。正则表达式匹配已经从正则表达式生成了一个 DFA,因此每次使用原始正则表达式时都会发生所提到的可怕的指数扩展步骤。一旦你付出了这个代价,就很容易(1)补充被认为是接受状态的状态集,并且(2)如果你通过遇到一个处于没有状态的符号“掉下”自动机就宣布成功该符号的过渡。
【解决方案2】:

您的问题包含两个问题,所以这里有几个答案。

完全不包含某个字符串(比如.config)的匹配行:

^(?:(?!\.config).)*$\r?\n?

在某个字符串中匹配不结束的行:

^.*(?<!\.config)$\r?\n?

并且,作为奖励:匹配不以特定字符串开始的行:

^(?!\.config).*$\r?\n?

(每次都包括换行符,如果存在的话。

哦,回答为什么您的版本不起作用:[^abc] 表示“除 a、b 或 c 之外的任何一 (1) 个字符”。您的其他解决方案也会在 test.hg 上失败(因为它也以字母 g 结尾 - 您的正则表达式单独查看每个字符而不是整个 .config 字符串。这就是您需要 lookaround 来处理此问题的原因。

【讨论】:

    【解决方案3】:
    (?<!\.config)$
    

    :)

    【讨论】:

      【解决方案4】:

      通过使用[^] 构造,您创建了一个否定字符类,它匹配除您命名的字符之外的所有字符。候选匹配中的字符顺序无关紧要,因此在任何具有[(\.config)(或[)gi.\onc(])的字符串上都会失败

      使用负前瞻(使用 perl 正则表达式),如下所示:(?!\.config$)。这将匹配所有不匹配文字“.config”的字符串

      【讨论】:

        【解决方案5】:

        除非你是“grepping”......因为你没有使用匹配的结果,为什么不搜索以 .config 结尾的字符串并跳过它们呢?在 Python 中:

        import re
        isConfig = re.compile('\.config$')
        # List lst is given
        filteredList = [f.strip() for f in lst if not isConfig.match(f.strip())]
        

        我怀疑这会比更复杂的 re. 运行得更快。

        【讨论】:

        • 除非你是 grepping,否则为什么要使用正则表达式呢? Python 有in 是有原因的。其他语言我肯定也有类似的解决方案。
        • 是的,这就是我现在所做的,但最好知道如何同时做到这一点。我遇到过这样的情况,这会导致一些尴尬的语法。
        【解决方案6】:

        正如您所要求的“更好的方法”:我会尝试一种“过滤”方法。我认为它很容易阅读和理解:

        #!/usr/bin/perl
        
        while(<>) {
            next if /\.config$/; # ignore the line if it ends with ".config"
            print;
        }
        

        如您所见,我以 perl 代码为例。但我想你明白了吗?

        添加: 这种方法也可以用来链接更多的过滤器模式,它仍然具有良好的可读性和易于理解性,

            next if /\.config$/; # ignore the line if it ends with ".config"
            next if /\.ini$/;    # ignore the line if it ends with ".ini"
            next if /\.reg$/;    # ignore the line if it ends with ".reg"
        
            # now we have filtered out all the lines we want to skip
            ... process only the lines we want to use ...
        

        【讨论】:

          【解决方案7】:

          我在找到此页面之前使用了Regexpal,当我想检查字符串是否不包含文件扩展名时,我提出了以下解决方案:

          ^(.(?!\.[a-zA-Z0-9]{3,}))*$ 我使用了m 复选框选项,以便我可以显示许多行并查看其中哪些匹配或不匹配。

          所以要找到一个不包含另一个你不想要的"^(.(?!" + 表达式的字符串+ "))*$"

          My article on the uses of this particular regex

          【讨论】:

            猜你喜欢
            • 2011-07-22
            • 2016-04-21
            • 2011-06-27
            • 1970-01-01
            • 1970-01-01
            • 2023-04-01
            • 2012-05-11
            • 2020-04-22
            • 1970-01-01
            相关资源
            最近更新 更多