【发布时间】:2019-12-10 21:21:44
【问题描述】:
在 c# 程序中,我想在可能存在其他文件的文件夹中写入文件。如果是这样,可以在文件中添加后缀myfile.docx、myfile (1).docx、myfile (2).docx 等等。
我正在努力分析现有文件名以提取现有文件的名称部分。
特别是,我使用这个正则表达式:(?<base>.+?)(\((?<idx>\d+)\)?)?(?<ext>(\.[\w\.]+))。
这个正则表达式输出:
╔═══════════════════════╦══════════════╦═════╦═══════════╦═══════════════════════════════════╗
║ Source Filename ║ base ║ idx ║ extension ║ Success ║
╠═══════════════════════╬══════════════╬═════╬═══════════╬═══════════════════════════════════╣
║ somefile.docx ║ somefile ║ ║ .docx ║ Yes ║
║ somefile ║ ║ ║ ║ No, base should be "somefile" ║
║ somefile (6) ║ ║ ║ ║ No, base should be "somefile (6)" ║
║ somefile (1).docx ║ somefile ║ 1 ║ .docx ║ Yes ║
║ somefile (2)(1).docx ║ somefile (2) ║ 1 ║ .docx ║ Yes ║
║ somefile (4).htm.tmpl ║ somefile ║ 4 ║ .htm.tmpl ║ Yes ║
╚═══════════════════════╩══════════════╩═════╩═══════════╩═══════════════════════════════════╝
如您所见,所有情况都有效,但文件名没有扩展名时除外。
如何修复我的正则表达式来解决失败的情况?
转载:https://regex101.com/r/q9uQii/1
如果有关系,这里是相关的 C# 代码:
private static readonly Regex g_fileNameAnalyser = new Regex(
@"(?<base>.+?)(\((?<idx>\d+)\)?)?(?<ext>(\.[\w\.]+))",
RegexOptions.Compiled | RegexOptions.ExplicitCapture
);
...
var candidateMatch = g_fileNameAnalyser.Match(somefilename);
var candidateInfo = new
{
baseName = candidateMatch.Groups["base"].Value.Trim(),
idx = candidateMatch.Groups["idx"].Success ? int.Parse(candidateMatch.Groups["idx"].Value) : 0,
ext = candidateMatch.Groups["ext"].Value
};
【问题讨论】:
-
为什么不在循环中检查文件是否存在,将索引递增一,直到找到可用的文件名?
-
使用
^(?<base>.+?)(?:\((?<idx>\d+)\))?(?<ext>\.[\w.]+)?$或^(?<base>.+?)\s*(?:\((?<idx>\d+)\))?(?<ext>\.[\w.]+)?$,见demo -
@PeterWolf:这可能是一个解决方案。我会考虑的
-
@WiktorStribiżew:您的正则表达式似乎按预期工作。你应该发布一个答案
-
对于最后一个示例,请注意操作系统将
.tmpl视为扩展名,将somefile (4).htm视为文件名,请参阅此fiddle。如果您可以调整您的要求,我将保留“扩展”的操作系统含义,使用Path.GetFileNameWithoutExension摆脱扩展,然后以某种方式解析生成的字符串以查找末尾的(可选)索引