摆脱文件名中的*连续*句点

时间:2010-08-02 17:40:34

标签: c#

我想知道如果我有一个像:

这样的文件名,我将如何删除文件名中的句点

测试.... 1.txt看起来像Test 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();
         }

        }

10 个答案:

答案 0 :(得分: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);
}

答案 1 :(得分:7)

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

答案 2 :(得分:5)

这个怎么样?

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

答案 3 :(得分:1)

为什么不使用这样的东西?

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

答案 4 :(得分:1)

您可以使用正则表达式,类似这样的

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

答案 5 :(得分: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();
}

答案 6 :(得分: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,但我对Regex的表现并不好,我可以做到这一点。

答案 7 :(得分: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"

答案 8 :(得分:1)

继续使用dark_charlie的解决方案,不是

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

足够?

答案 9 :(得分: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"