我想写一个正则表达式,它会递归地删除某些文件扩展名(不是全部)。要删除的扩展名为 .ready , .done 和 .error 。匹配应该通过一个组项目提供。
例如:
HelloWorld.xml --> HelloWorld.xml
Hello@World.xml.ready --> Hello@World.xml
Yaba_Daba-Doo.aaa.orig --> Yaba_Daba-Doo.aaa.orig
HelloWorld.xml.ready.error --> HelloWorld.xml
yogibear.xml.ready.done --> yogibear.xml
HelloWorld.bbb.done --> HelloWorld.bbb
Merry Chrismas.ready.yyy --> Merry Chrismas.ready.yyy
所以,我想出了以下简单的正则表达式 - ^(.+)(?:\.(?:ready|done|error))*$
唉,它没有按预期工作,因为(.+)
似乎是一个贪婪的匹配。
P.S。不幸的是,它可能是任何文件名。我唯一想要的是修剪任何尾随.ready
,.done
和/或.error
。我知道我可以在代码中完成它,但我有兴趣知道如何用正则表达式解决这个问题,因为我觉得它是可能的。
答案 0 :(得分:3)
这似乎太容易了,所以事情一定是错的,但无论如何我都会发布我的解决方案
您只需将第一组+
中的(.+)
替换为非贪婪版+?
即可。
最后的正则表达式变为这一个:^(.+?)(?:\.(?:ready|done|error))*$
你可以尝试使用这段代码:
string strRegex = @"^(.+?)(?:\.(?:ready|done|error))*$";
RegexOptions myRegexOptions = RegexOptions.None;
Regex myRegex = new Regex(strRegex, myRegexOptions);
string strTargetString = @"Merry Chrismas.ready.yyy";
string strReplace = @"${1}";
return myRegex.Replace(strTargetString, strReplace);
答案 1 :(得分:0)
这里最好的选择可能是首先匹配文件列表,然后像这样删除不需要的文件扩展名:
Regex regex = new Regex(@"\.(ready|done|error)$", RegexOptions.IgnoreCase);
fileNames = fileNames.Select(f => regex.Replace(f, "")).ToList();
我只是没有看到尝试匹配字符串开头的重点。
答案 2 :(得分:0)
试试这个
String[] test ={ "HelloWorld.xml", "HelloWorld.xml.ready", "HelloWorld.xml.orig", "HelloWorld.xml.ready.error", "HelloWorld.xml.ready.done", "HelloWorld.bbb.done", "HelloWorld.ready.yyy" };
var query = test.ToArray().Where(c => Regex.IsMatch(c,"(?:error|done|ready)$"));
foreach (String field in query)
{
Console.WriteLine(field);
}