开发者

Conditional Regex Replace in C# without MatchEvaluator

开发者 https://www.devze.com 2023-01-04 04:58 出处:网络
So, Im trying to make a program to rename some files. For the most part, I want them to look like this,

So, Im trying to make a program to rename some files. For the most part, I want them to look like this,

[Testing]StupidName - 2[720p].mkv

But, I would like to be able to change the format, if so desired. If I use MatchEvaluators, you would have to recompile every time. Thats why I don't want to use the MatchEvaluator.

The problem I have is that I don't know how, or if its possible, to tell Replace that if a group was found, include this string. The only syntax for this I have ever seen was something like (?<group>:data), but I can't get this to work. Well if anyone has an idea, im all for it.

EDIT:

Current Capture Regexes =

^(\[(?<FanSub>[^\]\)\}]+)\])?[. _]*(?<SeriesTitle>[\w. ]*?)[. _]*\-[. _]*(?<EpisodeNumber>\d+)[. _]*(\-[. _]*(?<EpisodeName>[\w. ]*?)[. _]*)?([\[\(\{](?<Mis开发者_StackOverflow中文版cInfo>[^\]\)\}]*)[\]\)\}][. _]*)*[\w. ]*(?<Extension>\.[a-zA-Z]+)$

^(?<SeriesTitle>[\w. ]*?)[. _]*[Ss](?<SeasonNumber>\d+)[Ee](?<EpisodeNumber>\d+).*?(?<Extension>\.[a-zA-Z]+)$    

^(?<SeriesTitle>[\w. ]*?)[. _]*(?<SeasonNumber>\d)(?<EpisodeNumber>\d{2}).*?(?<Extension>\.[a-zA-Z]+)$

Current Replace Regex = [${FanSub}]${SeriesTitle} - ${EpisodeNumber} [${MiscInfo}]${Extension}

Using Regex.Replace, the file TestFile 101.mkv, I get []TestFile - 1[].mkv. What I want to do is make it so that [] is only included if the group FanSub or MiscInfo was found.

I can solve this with a MatchEvaluator because I actually get to compile a function. But this would not be a easy solution for users of the program. The only other idea I have to solve this is to actually make my own Regex.Replace function that accepts special syntax.


It sounds like you want to be able to specify an arbitrary format dynamically rather than hard-code it into your code.

Perhaps one solution is to break your filename parts into specific groups then pass in a replacement pattern that takes advantage of those group names. This would give you the ability to pass in different replacement patterns which return the desired filename structure using the Regex.Replace method.

Since you didn't explain the categories of your filename I came up with some random groups to demonstrate. Here's a quick example:

string input = "Testing StupidName Number2 720p.mkv";
string pattern = @"^(?<Category>\w+)\s+(?<Name>.+?)\s+Number(?<Number>\d+)\s+(?<Resolution>\d+p)(?<Extension>\.mkv)$";

string[] replacePatterns =
{
    "[${Category}]${Name} - ${Number}[${Resolution}]${Extension}",
    "${Category} - ${Name} - ${Number} - ${Resolution}${Extension}",
    "(${Number}) - [${Resolution}] ${Name} [${Category}]${Extension}"
};

foreach (string replacePattern in replacePatterns)
{
    Console.WriteLine(Regex.Replace(input, pattern, replacePattern));
}

As shown in the sample, named groups in the pattern, specified as (?<Name>pattern), are referred to in the replacement pattern by ${Name}.

With this approach you would need to know the group names beforehand and pass these in to rearrange the pattern as needed.

0

精彩评论

暂无评论...
验证码 换一张
取 消