正则表达式所有不包含字符串的字符串?

Regex for all strings not containing a string?

本问题已经有最佳答案,请猛点这里访问。

好吧,这是一件非常愚蠢的事情,但这是我从来没有学会做的事情,这是一件麻烦事。

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

我想我可以

1
.*[^(\.config)]$

但这不管用(为什么不呢?)

我知道我能做到

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

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


您可以使用反向查找,例如:

1
.*(?<!\.config)$

除了以".config"结尾的字符串外,它匹配所有字符串。


你的问题有两个问题,所以这里有几个答案。

匹配根本不包含特定字符串的行(如.config

1
2
3
^(?:(?!\.config).)*$
?
?

匹配不以特定字符串结尾的行:

1
2
3
^.*(?<!\.config)$
?
?

还有,作为奖励:匹配不以特定字符串开头的行:

1
2
3
^(?!\.config).*$
?
?

(如果有,每次包括换行符。

哦,为了回答为什么你的版本不起作用:[^abc]的意思是"除了a、b或c之外的任何一(1)个字符"。您的另一个解决方案也会在test.hg上失败(因为它也以字母g结尾-您的regex单独查看每个字符,而不是整个.config字符串。这就是为什么你需要四处看看。


1
(?<!\.config)$

:)


正如您所要求的"更好的方法":我将尝试"过滤"方法。我觉得很容易阅读和理解:

1
2
3
4
5
6
#!/usr/bin/perl

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

如您所见,我使用了Perl代码作为示例。但我想你明白了吗?

补充:这种方法还可以用于链接更多的过滤模式,并且仍然保持良好的可读性和易于理解。

1
2
3
4
5
6
    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 ...

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

使用否定的lookahead(使用perl regexs),比如:(?!\.config$)。这将匹配所有与文本".config"不匹配的字符串。


除非你是"伟大的"…既然您没有使用匹配结果,为什么不搜索以.config结尾的字符串并跳过它们呢?在Python中:

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

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


在找到这个页面之前,我使用了ReXExpAL,并在检查字符串不包含文件扩展名时提出了以下解决方案:

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

因此,要找到一个不包含另一个"^(.(?!" +表达式的字符串,就不需要+"))*$"

我关于这个特殊regex用法的文章