Rename file using regular expression

2019-05-26 17:34发布

What I want to do is rename all file in a particular folder, such that if a filename contains any digit in it, it is removed.

say, if a filename is someFileName.someExtension it remains the same, but if a file is like this, 03 - Rocketman Elton John it should be renamed to Rocketman Elton John (I did the part to remove the -), another example, if the filename is 15-Trey Songz - Unfortunate (Prod. by Noah 40 Shebib) it should be renamed to Trey Songz Unfortunate (Prod. by Noah Shebib) (again I can remove -). The user is asked to select the folder like this

private void txtFolder_MouseDown(object sender, MouseEventArgs e)
        {
            FolderBrowserDialog fd = new FolderBrowserDialog();
            fd.RootFolder = Environment.SpecialFolder.Desktop;
            fd.ShowNewFolderButton = true;
            if (fd.ShowDialog() == DialogResult.OK)
            {
                txtFolder.Text = fd.SelectedPath;
            }
        }

Also, it renaming starts like this

private void btnGo_Click(object sender, EventArgs e)
{
    StartRenaming(txtFolder.Text);
}

and

private void StartRenaming(string FolderName)
{
   string[] files = Directory.GetFiles(FolderName);
   foreach (string file in files)
        RenameFile(file);
}

Now in rename file, I need the function, the regular expression that will remove any number(s) in file. Its is implemented as

private void RenameFile(string FileName)
{
    string fileName = Path.GetFileNameWithoutExtension(FileName);
   /* here the function goes that will find numbers in filename using regular experssion and replace them */ 
}

so what I can do is, I can use something like

1  var matches = Regex.Matches(fileName, @"\d+");
2  
3  if (matches.Count == 0)
4    return null;
5
6  // start the loop
7  foreach(var match in matches)
8  {
9     fileName = fileName.Replace(match, ""); /* or fileName.Replace(match.ToString(), ""), whatever be the case */    
10 }
11  File.Move(FileName, Path.Combine(Path.GetDirectoryName(FileName), fileName));
12  return;

But I don't think that's the right way to do it? Is there any better option to do this? or is this the best (and only option) to do this? Also, is there anything like IN in String.Replace? Say in sql I can use IN in a select command and specify a bunch of where conditions, but is there something like this with String.Replace so that I don't have to run the loop I ran from line 7 to 10? Are there any other better options?

ps: about that regex, I posted a question Regular Expression for numbers? (apparently I wasn't clear enough) and from that I got my regex, if you think someother regex would do better please tell me, also if you need any other information please let me know...

5条回答
家丑人穷心不美
2楼-- · 2019-05-26 18:00

In the off chance that you are merely looking to simply rename the files and you thought that creating your own program would be the best way - I would recommend PFrank as a standalone tool (especially if you understand regex already)

If you do desire this and if you do take my suggestion (and since it's not the simplest and clearest interface), you would use \d+(\s?-)? for the match expression (in the first column in PFrank), which should match any number of digits, optionally followed by a hyphen and an additional optional whitespace character between the two. You would then have no replacement expression (zero-length string or an empty second column in PFrank). Finally, select the folder containing the files you want renamed and click the scan button; in the dialog that pops up, confirm your results and click the rename button. Sorry if I wasted anyone's time!

查看更多
相关推荐>>
3楼-- · 2019-05-26 18:02

I prefer to use brackets to select the before and after and then use the $n method to rebuild the string how you want it to be.

"03 - Rocketman Elton John"  -Replace '^([^-]*) - ([^-]*)', '$1 $2'
查看更多
来,给爷笑一个
4楼-- · 2019-05-26 18:04

You can try Regex.Replace to remove digits, ie:

Regex.Replace(fileName, @"\d", "");
查看更多
Melony?
5楼-- · 2019-05-26 18:09

How about this ?

private void StartRenaming(string FolderName)
{
    string[] files = Directory.GetFiles(FolderName);
    string[] applicableFiles = (from string s in files
                                where Regex.IsMatch(s, @"(\d+)|(-+)", RegexOptions.None)
                                select s).ToArray<string>();

    foreach (string file in applicableFiles)
        RenameFile(file);
}

private void RenameFile(string file)
{
    string newFileName = Regex.Replace(file, @"(\d+)|(-+)", "");
    File.Move(file, Path.Combine(Path.GetDirectoryName(file), newFileName));
}

StartRenaming method will now limit the number of files to be processed based on Regex match. If the file contains a digit or - then it will be processed, thus optimizing the complete process. RenameFile replaces digits and - in a string and gives you a newFileName

I am not quite sure about the correctness of File.Move(file, Path.Combine(Path.GetDirectoryName(file), newFileName)); though, but I guess your problem was to avoid the foreach loop, and I think I have provided an appropriate solution.

Please note that I was not able to completely test this, so let me know whether it works for you and if it doesn't I will be happy to help you further.

EDIT : Forgot to mention that file.Replace(@"(\d+)|(-+)", "") will remove digits as well as - from the file string.

EDIT : Corrected file.Replace to Regex.Replace

查看更多
We Are One
6楼-- · 2019-05-26 18:14

For replacing you should look into Regex.Replace which can replace all occurences at once.

Otherwise code look ok (with exception of strange fileName.Replace("match", "") which uses constant string...)

查看更多
登录 后发表回答