需要正则表达式来排除某些字符串

时间:2008-11-24 16:18:36

标签: regex

我正在尝试获得匹配的正则表达式:

somefile_1.txt
somefile_2.txt
somefile_{anything}.txt

但不匹配:

somefile_16.txt

我试过

somefile_[^(16)].txt

没有运气(甚至包括“16”记录)

6 个答案:

答案 0 :(得分:11)

一些正则表达式库允许前瞻:

somefile(?!16\.txt$).*?\.txt

否则,您仍然可以使用多个字符类:

somefile([^1].|1[^6]|.|.{3,})\.txt

或者,为了实现最大的可移植性:

somefile([^1].|1[^6]|.|....*)\.txt

[^(16)]表示:匹配任何字符,但大括号,1和6。

答案 1 :(得分:5)

已经提到了最佳解决方案:

somefile_(?!16\.txt$).*\.txt

这很有效,并且贪得无厌,可以在同一条线上接收任何东西。但是,如果您知道您需要有效的文件名,我建议您也限制无效字符:

somefile_(?!16)[^?%*:|"<>]*\.txt

如果你正在使用不支持前瞻的正则表达式引擎,你将不得不考虑如何弥补它!16。您可以将文件分成两组,一组以1开头,后面不是6,以及以其他任何方式开头的组:

somefile_(1[^6]|[^1]).*\.txt

如果你想允许somefile_16_stuff.txt而不是somefile_16.txt,那么上面的这些正则表达式是不够的。您需要以不同方式设置限制:

somefile_(16.|1[^6]|[^1]).*\.txt

将这一切结合起来,最终会有两种可能性,一种阻塞单个实例(somefile_16.txt),另一种阻塞所有系列(somefile_16 * .txt)。我个人认为你更喜欢第一个:

somefile_((16[^?%*:|"<>]|1[^6?%*:|"<>]|[^1?%*:|"<>])[^?%*:|"<>]*|1)\.txt
somefile_((1[^6?%*:|"<>]|[^1?%*:|"<>])[^?%*:|"<>]*|1)\.txt

在不删除特殊字符的版本中,因此更容易阅读:

somefile_((16.|1[^6]|[^1).*|1)\.txt
somefile_((1[^6]|[^1]).*|1)\.txt

答案 2 :(得分:4)

严格遵守您的规范并挑剔,您应该使用:

^somefile_(?!16\.txt$).*\.txt$

这样可以匹配{anything}的somefile_1666.txt;)

但有时使用它会更具可读性:

ls | grep -e 'somefile_.*\.txt' | grep -v -e 'somefile_16\.txt'

答案 3 :(得分:3)

somefile_(?!16).*\.txt

(?!16)表示:断言从该位置开始无法匹配正则表达式“16”。

答案 4 :(得分:2)

有时使用两个正则表达式会更容易。首先寻找你想要的一切,然后忽略你不想要的一切。我一直在命令行上执行此操作,我将一个正则表达式转换为另一个正则表达式,该正则表达式忽略了我不想要的东西。

如果目标是完成工作而不是找到完美的正则表达式,那么请考虑这种方法。编写和理解通常比利用异域特征的正则表达式更容易。

答案 5 :(得分:1)

不使用前瞻

somefile_(|.|[^1].+|10|11|12|13|14|15|17|18|19|.{3,}).txt

阅读如下:somefile_后跟:

  1. 没有
  2. 一个角色。
  3. 1以外的任何一个字符,后跟任何其他字符。
  4. 三个或更多字符。
  5. 10 .. 19请注意16已被遗漏。
  6. 最后是.txt