2

我想编写一个正则表达式,它会递归地去除某些文件扩展名(不是全部)。要剥离的扩展名是.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))*$

唉,它没有按预期工作,因为(.+)似乎是一个贪婪的匹配。

PS 不幸的是,它可以是任何文件名。我唯一想要的是修剪任何尾随.ready,.done和/或.error. 我知道我可以在代码中做到这一点,但我有兴趣知道如何用正则表达式解决这个问题,因为我觉得这是可能的。

4

3 回答 3

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);
于 2013-08-01T14:16:13.053 回答
0

也许这里最好的选择是首先匹配文件列表,然后像这样去除不需要的文件扩展名:

Regex regex = new Regex(@"\.(ready|done|error)$", RegexOptions.IgnoreCase);
fileNames = fileNames.Select(f => regex.Replace(f, "")).ToList();

我只是看不到尝试匹配字符串的开头的意义。

于 2013-08-01T14:17:47.700 回答
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);
}
于 2013-08-01T14:18:18.650 回答