2010-08-02 61 views
2

我想知道如何删除文件名中的句号如果我有一个文件名如:摆脱文件名*连续*期间

测试.... 1.txt看起来像测试1.txt?我不想要像下面这样的文件:1.0.1 Test.txt被触动。只有具有连续期间的文件应该用空格替换。有任何想法吗?

这是我当前的代码,但你可以看到,它从时间预留替换每一个时期的扩展名:

public void DoublepCleanUp(List<string> doublepFiles) 
    { 
     Regex regExPattern2 = new Regex(@"\s{2,}"); 
     Regex regExPattern4 = new Regex(@"\.+"); 
     Regex regExPattern3 = new Regex(@"\.(?=.*\.)"); 
     string replace = " "; 
     List<string> doublep = new List<string>(); 
     var filesCount = new Dictionary<string, int>(); 

     try 
     { 
      foreach (string invalidFiles in doublepFiles) 
      { 
       string fileOnly = System.IO.Path.GetFileName(invalidFiles); 
       string pathOnly = System.IO.Path.GetDirectoryName(fileOnly); 

       if (!System.IO.File.Exists(fileOnly)) 
       { 
        string filewithDoublePName = System.IO.Path.GetFileName(invalidFiles); 
        string doublepPath = System.IO.Path.GetDirectoryName(invalidFiles); 
        string name = System.IO.Path.GetFileNameWithoutExtension(invalidFiles); 
        //string newName = name.Replace(".", " "); 
        string newName = regExPattern4.Replace(name, replace); 
        string newName2 = regExPattern2.Replace(newName, replace); 
        string filesDir = System.IO.Path.GetDirectoryName(invalidFiles); 
        string fileExt = System.IO.Path.GetExtension(invalidFiles); 
        string fileWithExt = newName2 + fileExt; 
        string newPath = System.IO.Path.Combine(filesDir, fileWithExt); 
        System.IO.File.Move(invalidFiles, newPath); 


        DataGridViewRow clean = new DataGridViewRow(); 
        clean.CreateCells(dataGridView1); 
        clean.Cells[0].Value = doublepPath; 
        clean.Cells[1].Value = filewithDoublePName; 
        clean.Cells[2].Value = fileWithExt; 
        dataGridView1.Rows.Add(clean); 
       } 

       else 
       { 
        if (filesCount.ContainsKey(fileOnly)) 
        { 
         filesCount[fileOnly]++; 
        } 
        else 
        { 
         filesCount.Add(fileOnly, 1); 
         string newFileName = String.Format("{0}{1}{2}", 
          System.IO.Path.GetFileNameWithoutExtension(fileOnly), 
          filesCount[fileOnly].ToString(), 
          System.IO.Path.GetExtension(fileOnly)); 

         string newFilePath = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(fileOnly), newFileName); 
         System.IO.File.Move(fileOnly, newFilePath); 

         DataGridViewRow clean = new DataGridViewRow(); 
         clean.CreateCells(dataGridView1); 
         clean.Cells[0].Value = pathOnly; 
         clean.Cells[1].Value = fileOnly; 
         clean.Cells[2].Value = newFileName; 
         dataGridView1.Rows.Add(clean); 
        } 

       } 
      } 
     } 
     catch(Exception e) 
     { 
     //throw; 
      StreamWriter doublepcleanup = new StreamWriter(@"G:\DoublePeriodCleanup_Errors.txt"); 
      doublepcleanup.Write("Double Period Error: " + e + "\r\n"); 
      doublepcleanup.Close(); 
     } 

     } 

回答

7
string name = "Text...1.txt"; 
Regex r = new Regex("[.][.]+"); 
string result = r.Replace(name, " "); 
7

好,做一个字符串:

string st = "asdf..asdf...asfd...asdf.asf.asdf.s.s"; 
Regex r = new Regex("\\.\\.+"); 
st = r.Replace(st, " "); 

这将用空格替换2个或更多'.'的任何实例。

我就把它放到方法:

public static string StringReplace(string original, 
            string regexMatch, string replacement) { 
    Regex r = new Regex(regexMatch); 
    return r.Replace(original, replacement); 
} 
+0

唯一的问题与此是文件 “测试...... JPG” – Struan 2010-08-02 18:24:08

+1

@Struan,真实。在这种情况下,这确实失败了。可能只是想为它添加一个特例。 – jjnguy 2010-08-02 18:27:48

5

这个怎么样?

string newFileName = String.Join(".", fileName.Split('.').Select(p => !String.IsNullOrEmpty(p) ? p : " ").ToArray()) 
1

为什么不使用这样的事情?

string newName = name; 
while (newName.IndexOf("..") != -1) 
    newName = newName.Replace("..", " "); 
+2

这会增加很多空间。例如“Test ...... 1.txt”将会有3个空格。 – 2010-08-02 17:54:42

1

你可以使用使用正则表达式,像这样

string fileName = new Regex(@"[.][.]+").Replace(oldFileName, ""); 
+0

您的regix可以像'“[。] [。] +”'一样简单,您应该用空格而不是空字符串替换。 – jjnguy 2010-08-02 18:01:49

1
static string CleanUpPeriods(string filename) 
{ 
    StringBuilder sb = new StringBuilder(); 
    if (filename.Length > 0) sb.Append(filename[0]); 
    for (int i = 1; i < filename.Length; i++) 
    { 
     char last = filename[i - 1]; 
     char current = filename[i]; 
     if (current != '.' || last != '.') sb.Append(current); 
    } 
    return sb.ToString(); 
} 
1
void ReplaceConsecutive(string src, int lenght, string replace) 
{ 
    char last; 
    int count = 0; 
    StringBuilder ret = new StringBuilder(); 
    StringBuilder add = new StringBuilder(); 
    foreach (char now in src) 
    { 
     if (now == last) 
     { 
      add.Append(now); 
      if (count > lenght) 
      { 
       ret.Append(replace); 
        add = new StringBuilder(); 
      } 
      count++; 
     } 
     else 
     { 
      ret.Append(add); 
      add = new StringBuilder(); 
      count = 0; 
      ret.Append(now); 
     } 
    } 
    return ret.ToString(); 
} 

未经检验的,但这应该工作。

src是您想要检查连续的字符串,lenght是相等的字符数量,直到它们被replace替换为止。 这是AFAIK在正则表达式中也是可能的,但我用正则表达式并不是那么好,我可以做到这一点。

1

我已经在很多情况下测试了这段代码,它似乎表现出所要求的行为。

private static string RemoveExcessPeriods(string text) 
    { 
     if (string.IsNullOrEmpty(text)) 
      return string.Empty; 
     // If there are no consecutive periods, then just get out of here. 
     if (!text.Contains("..")) 
      return text; 
     // To keep things simple, let's separate the file name from its extension. 
     string extension = Path.GetExtension(text); 
     string fileName = Path.GetFileNameWithoutExtension(text); 
     StringBuilder result = new StringBuilder(text.Length); 
     bool lastCharacterWasPeriod = false; 
     bool thisCharacterIsPeriod = fileName.Length > 0 && fileName[0] == '.'; 
     bool nextCharacterIsPeriod; 
     for (int index = 0; index < fileName.Length; index++) 
     { 
      // Includes both the extension separator and other periods. 
      nextCharacterIsPeriod = fileName.Length == index + 1 || fileName[index + 1] == '.'; 

      if (!thisCharacterIsPeriod) 
       result.Append(fileName[index]); 
      else if (thisCharacterIsPeriod && !lastCharacterWasPeriod && !nextCharacterIsPeriod) 
       result.Append('.'); 
      else if (thisCharacterIsPeriod && !lastCharacterWasPeriod) 
       result.Append(' '); 

      lastCharacterWasPeriod = thisCharacterIsPeriod; 
      thisCharacterIsPeriod = nextCharacterIsPeriod; 
     } 
     return result.ToString() + extension; 
    } 

我只是做了一些改变来处理一些边缘情况。这里是这个版本的一些测试结果。

"Test....1.txt" => "Test 1.txt" 
"1.0.1..Test.txt" => "1.0.1 Test.txt" 
"Test......jpg" => "Test .jpg" 
"Test.....jpg" => "Test .jpg" 
"one.pic.jpg" => "one.pic.jpg" 
"one..pic.jpg" => "one pic.jpg" 
"one..two..three.pic.jpg" => "one two three.pic.jpg" 
"one...two..three.pic.jpg" => "one two three.pic.jpg" 
"one..two..three.pic..jpg" => "one two three.pic .jpg" 
"one..two..three..pic.jpg" => "one two three pic.jpg" 
"one..two..three...pic...jpg" => "one two three pic .jpg" 
1

从dark_charlie的解决方案继续,是不是

string newName = name; 
while (newName.IndexOf("..") != -1) 
    newName = newName.Replace("..", "."); 

就够了吗?

1

结合一些其他的答案...

static string CleanUpPeriods(string filename) 
{ 
    string extension = Path.GetExtension(filename); 
    string name = Path.GetFileNameWithoutExtension(filename); 
    Regex regex = new Regex(@"\.\.+"); 
    string s = regex.Replace(name, " ").Trim(); 
    if (s.EndsWith(".")) s = s.Substring(0, s.Length - 1); 
    return s + extension; 
} 

样本输出

"Test........jpg" -> "Test.jpg" 
"Test....1.jpg" -> "Test 1.jpg" 
"Test 1.0.1.jpg" -> "Test 1.0.1.jpg" 
"Test..jpg" -> "Test.jpg"