簡體   English   中英

提取文件名部分以解決文件名沖突

[英]Extract filename parts to solve file name conflict

在 ac# 程序中,我想在可能存在其他文件的文件夾中寫入文件。 如果是這樣,可以將后綴添加到文件myfile.docxmyfile (1).docxmyfile (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
};

你可以做的是重復包含數字的()部分,斷言有下一對。 然后使用數字作為idx組捕獲下一部分。

使用問號將 idx 組和 ext 組設為可選。

^(?<base>[^\r\n.()]+(?:(?:\(\d+\))*(?=\(\d+\)))?)(?:\((?<idx>\d+)\))?(?<ext>(?:\.[\w\.]+))?$
  • ^字符串開始
  • (?<base>開始base
    • [^\\r\\n.()]+匹配 1+ 次除所列字符以外的任何字符
    • (?:非捕獲組
      • (?:\\(\\d+\\))*(?=\\(\\d+\\))重復匹配(digits)直到右邊剩下 1 (digits)部分
    • )? 關閉組並使其成為可選
  • )base
  • (?:\\((?<idx>\\d+)\\))? ()之間匹配idx組的可選部分
  • (?<ext>(?:\\.[\\w\\.]+))? 可選ext
  • $字符串結尾

正則表達式演示

您可以使用

^(?<base>.+?)\s*(?:\((?<idx>\d+)\))?(?<ext>\.[\w.]+)?$

查看正則表達式演示,結果:

在此處輸入圖片說明

圖案詳情

  • ^ - 字符串的開始
  • (?<base>.+?) - 組“base”:除換行符以外的任何 1 個或多個字符,盡可能少
  • \\s* - 0+ 個空格
  • (?:\\((?<idx>\\d+)\\))? - 一個可選的序列:
    • \\( - a (字符
    • (?<idx>\\d+) - 組“idx”:1+ 位數字
    • \\) - a )字符
  • (?<ext>\\.[\\w.]+)? -- 一個可選的組“ext”:
    • \\. - 一個. 字符
    • [\\w.]+ - 1+ 個字母、數字、 _. 字符
  • $ - 字符串的結尾。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM