2010-07-20 24 views
4

我正在嘗試使文件名看起來像:
MAX_1.01.01.03.pdf看起來像Max_1010103.pdf。擺脫文件名中的多個句點的問題

目前我有這樣的代碼:

public void Sanitizer(List<string> paths) 
{ 
    string regPattern = (@"[~#&!%+{}]+"); 
    string replacement = " "; 

    Regex regExPattern = new Regex(regPattern); 
    Regex regExPattern2 = new Regex(@"\s{2,}"); 
    Regex regExPattern3 = new Regex(@"\.(?=.*\.)"); 
    string replace = ""; 

    var filesCount = new Dictionary<string, int>(); 
    dataGridView1.Rows.Clear(); 

    try 
    { 
    foreach (string files2 in paths) 
    { 
     string filenameOnly = System.IO.Path.GetFileName(files2); 
     string pathOnly = System.IO.Path.GetDirectoryName(files2); 
     string sanitizedFileName = regExPattern.Replace(filenameOnly, replacement); 
     sanitizedFileName = regExPattern2.Replace(sanitizedFileName, replacement); 
     string sanitized = System.IO.Path.Combine(pathOnly, sanitizedFileName); 

     if (!System.IO.File.Exists(sanitized)) 
     { 
     DataGridViewRow clean = new DataGridViewRow(); 
     clean.CreateCells(dataGridView1); 
     clean.Cells[0].Value = pathOnly; 
     clean.Cells[1].Value = filenameOnly; 
     clean.Cells[2].Value = sanitizedFileName; 

     dataGridView1.Rows.Add(clean); 
     System.IO.File.Move(files2, sanitized); 
     } 
     else 
     { 
     if (filesCount.ContainsKey(sanitized)) 
     { 
      filesCount[sanitized]++; 
     } 
     else 
     { 
      filesCount.Add(sanitized, 1); 
      string newFileName = String.Format("{0}{1}{2}", 
       System.IO.Path.GetFileNameWithoutExtension(sanitized), 
       filesCount[sanitized].ToString(), 
       System.IO.Path.GetExtension(sanitized)); 

      string newFilePath = System.IO.Path.Combine(
       System.IO.Path.GetDirectoryName(sanitized), newFileName); 
      newFileName = regExPattern2.Replace(newFileName, replacement); 
      System.IO.File.Move(files2, newFilePath); 
      sanitized = newFileName; 

      DataGridViewRow clean = new DataGridViewRow(); 
      clean.CreateCells(dataGridView1); 
      clean.Cells[0].Value = pathOnly; 
      clean.Cells[1].Value = filenameOnly; 
      clean.Cells[2].Value = newFileName; 

      dataGridView1.Rows.Add(clean); 
     } 

//HERE IS WHERE I AM TRYING TO GET RID OF DOUBLE PERIODS// 
     if (regExPattern3.IsMatch(files2)) 
     { 
      string filewithDoublePName = System.IO.Path.GetFileName(files2); 
      string doublepPath = System.IO.Path.GetDirectoryName(files2); 
      string name = System.IO.Path.GetFileNameWithoutExtension(files2); 
      string newName = name.Replace(".", ""); 
      string filesDir = System.IO.Path.GetDirectoryName(files2); 
      string fileExt = System.IO.Path.GetExtension(files2); 
      string newPath = System.IO.Path.Combine(filesDir, newName+fileExt); 

      DataGridViewRow clean = new DataGridViewRow(); 
      clean.CreateCells(dataGridView1); 
      clean.Cells[0].Value =doublepPath; 
      clean.Cells[1].Value = filewithDoublePName; 
      clean.Cells[2].Value = newName; 
      dataGridView1.Rows.Add(clean); 
     } 
     } 
    } 
    catch (Exception e) 
    { 
     throw; 
     //errors.Write(e); 
    } 
    } 

我跑了這一點,而不是擺脫ALL期(減去文件擴展名之前的期間),我得到這樣的結果:MAX_1.0103.pdf

如果有是多個時期,例如:Test....1.txt我得到這些結果:Test...1.txt

它似乎只擺脫了一個時期。我非常新的正則表達式,它是這個項目的要求。任何人都可以幫我找出我在做什麼錯在這裏?

謝謝!

編輯以顯示代碼所做

+0

爲什麼不直接從後面保持第一段時間?我不知道如何在c#中編寫它,但它會是這樣的:s /(\。(?!\ w + $))// g尋找未來前瞻無法找到單詞的點+文件。所有匹配的東西都應該被替換爲無。 (也不知道c#是否支持負向預覽:/) – NorthGuard 2010-07-20 16:24:14

+0

爲什麼正則表達式是這個項目的一個需求?僅僅因爲你*可以*用RegEx做某件事並不意味着你*應該*。 – ChrisF 2010-07-20 17:06:37

回答

12

爲什麼不使用Path class

string name = Path.GetFileNameWithoutExtension(yourPath); 
string newName = name.Replace(".", ""); 
string newPath = Path.Combine(Path.GetDirectoryName(yourPath), 
           newName + Path.GetExtension(yourPath)); 

爲了清楚起見分開的每個步驟。

所以對於輸入

「C:\用戶\弗雷德\ MAX_1.01.01.03.pdf」

我得到的輸出

「C:\ Users \ Fred \ MAX_1010103.pdf「

這是我所期望的。

如果我提供:

「C:\用戶\ Fred.Flintstone \ MAX_1.01.01.03.pdf」

我得到:

「C: \ Users \ Fred.Flintstone \ MAX_1010103.pdf「

再次我所期待的,因爲我沒有處理」 DirectoryName「路徑的一部分。

注意我錯過了RegEx作爲一項必備條件。儘管如此,仍然堅持這個答案。

+0

這會照顧一個文件名中的句點的所有實例嗎?如果我有像測試....... 1.txt這樣的東西? – yeahumok 2010-07-20 16:33:55

+1

@yeahumok - yes - 「返回一個新字符串,其中當前字符串中指定的Unicode字符或字符串的所有出現處都被替換爲另一個指定的Unicode字符或字符串。」 http://msdn.microsoft.com/en-us/library/system.string.replace.aspx – ChrisF 2010-07-20 16:35:03

+0

嗯這太奇怪了。我在我的代碼中實現了這一點...但是我不斷得到一些仍包含句點的結果。我編輯了我的代碼 - 我在這裏做錯了什麼?! – yeahumok 2010-07-20 19:06:25

-1

這樣的事情,也許變化:

string fileName = "MAX_1.01.01.03.pdf"; 
fileName = fileName.Substring(0, 1).ToUpper() + fileName.Substring(1).ToLower(); 
fileName = fileName.Replace(".", ""); 
0

我會放棄正則表達式都在一起,像這樣做:

  1. 全部替換週期空字符串
  2. 最後3個 字符(替換 「」 +最後3 個字符)
+1

不適用於多於或少於3個字符的擴展程序,例如「.html」 – M4N 2010-07-20 16:19:31

2

說,你沒有already ask this question

無論如何,我堅持my original answer

string RemovePeriodsFromFilename(string fullPath) 
{ 
    string dir = Path.GetDirectoryName(fullPath); 
    string filename = Path.GetFileNameWithoutExtension(fullPath); 
    string sanitized = filename.Replace(".", string.Empty); 
    string ext = Path.GetExtension(fullPath); 

    return Path.Combine(dir, sanitized + ext); 
} 

現在,既然你指定你必須使用正則表達式,我想你可以始終它在那裏:

string RemovePeriodsFromFilename(string fullPath) 
{ 
    string dir = Path.GetDirectoryName(fullPath); 
    string filename = Path.GetFileNameWithoutExtension(fullPath); 

    // Look! Now the solution uses RegEx! 
    string sanitized = Regex.Replace(filename, @"\.", string.Empty); 

    string ext = Path.GetExtension(fullPath); 

    return Path.Combine(dir, sanitized + ext); 
} 

注意:這基本上與ChrisF建議的完全相同。

無論誰要求您使用RegEx,我建議您請求解釋原因。

+1

對於RegEx我可以理解+1;) – ChrisF 2010-07-20 17:08:06

0

這個正則表達式會除去3或4個字母擴展前的所有句點。

string filename = "test.test......t.test.pdf";  
string newFilename = new Regex(@"\.(?!(\w{3,4}$))").Replace(filename, ""); 

如果你想讓它有2名字母的擴展工作,只是改變了{3,4}到{2,4}

祝你好運!

+2

...或者只是使用'\。(?!([^。] + $))' – 2010-07-21 19:21:49

+0

我確實考慮過,但是如果用戶使用MacOSX並上傳沒有擴展名的文件?例如:Snicker.Doodles?生成的文件名應該是SnickerDoodles! – Snickers 2010-07-23 19:08:44

+0

雖然我猜你有擴展名,如.compiled,.library和.torrent - 在這種情況下,你的正則表達式會更好! – Snickers 2010-07-23 19:18:31