2010-07-20 87 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