我正在尝试获得匹配的正则表达式:
somefile_1.txt
somefile_2.txt
somefile_{anything}.txt
但不匹配:
somefile_16.txt
我试过
somefile_[^(16)].txt
没有运气(甚至包括“16”记录)
答案 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
以外的任何一个字符,后跟任何其他字符。10
.. 19
请注意16
已被遗漏。最后是.txt
。