Regex只匹配一些文件名

Regex to match only some filenames

本文关键字:文件名 Regex      更新时间:2023-10-16

使用std::regex并给定一个文件路径,我想只匹配以.txt结尾且不属于_test.txt.txtTEMP形式的文件名。其他下划线都可以

例如:

  • somepath/testFile.txt应匹配
  • somepath/test_File.txt应该匹配
  • somepath/testFile_test.txt不匹配
  • somepath/testFile.txtTEMP不匹配

这种模式的正确正则表达式是什么?

我试过了:

(.*?)(.txt) ->匹配任何以.txt结尾的文件路径。

要排除包含_test的文件,我尝试使用负查找:

(.*?)(?!_test)(.txt)

但是没有成功。

我也尝试过消极的后面看,但MSVC14 (Visual Studio 2015)在创建regex时抛出std::regex_error异常,所以我不确定它是否不受支持,或者我使用错误的语法。

根据你发布的内容,使用这个模式

^(?!.*_).*.txt$

演示

或基于OP编辑

的模式
^(.*(?<!_test).txt$)
演示

^(?!.*?_test.).*.txt$

我没有访问VS 2015 atm,但这只使用向前看,所以应该工作

最好的选择?不要使用正则表达式。特别是在像这样的简单字符串搜索情况下。

首先,根据问题的参数,可以进行一些简单的优化:

  1. 由于输入string的扩展名必须是:".txt",我们不需要检查扩展名是否为".txtTEMP"
  2. 唯一不匹配的条件,然后,输入string以"_test.txt"结束,需要检查干以"_test"结束,因为扩展名已经知道是:"。txt"

这两个检查总是将从输入string的末尾偏移固定数量的字符。因为这两个表达式的所有信息都是已知的,所以应该在编译时设置:

constexpr auto doMatch = ".txt";
constexpr auto doMatchSize = strlen(doMatch);
constexpr auto doNotMatch = "_test";
constexpr auto doNotMatchSize = strlen(doNotMatch) + doMatchSize;

给定string input,它可以测试成功,如下所示:

if(input.size() >= doMatchSize &&
   equal(input.end() - doMatchSize, input.end(), doMatch) &&
   (input.size() < doNotMatchSize ||
   !equal(input.end() - doNotMatchSize, input.end() - doMatchSize, doNotMatch)))

您可以在这里看到一个活生生的例子:http://ideone.com/7BcyFi

模拟您真正想要的向后查找(但不幸的是c++ 11不支持)的一个技巧是反转字符串,然后使用向前查找。你的regexp会变成像

这样的东西
^txt.(?!tset_).*

您尝试的前瞻性的问题是,它适用于它也应该开始匹配'.txt的位置。的一部分。所以regexp的部分'(?!_test)(.txt)'表示'我想要一些不以_test开头的东西,但与。txt匹配'。任何以。txt结尾的内容都将与之匹配,这就是为什么它不起作用。

更新:一个反向查找的正则表达式(这在c++中不起作用,但在例如python中起作用):

^.*(?<!_test).txt$