c# - 如何使用正则表达式替换字符串

标签 c# regex string replace

我有一些想法如何在 string.replace 方法中使用正则表达式来“匹配”值,但实际上不知道如何操作它们。我尝试通过查找文件名中的以下常见模式并用更标准化的命名约定替换它们来重命名文件。

这是我尝试替换的示例:

“1x01” “01x01” “101” “S01E” “S01E” “S1E” “S1E” “S1x”

并将其替换为 S01xE01,其中 S01 代表第 1 季,E01 代表第 1 集,因此数值当然会有变化...我的想法是正则表达式,但在浏览下一个之后,我不会找到特定的足够的例子来帮助我。

我陷入困境的部分原因是即使我找到了匹配的表达式,我也不知道如何进行替换。例如,如果我执行 string.replace("S\d*E\d*","我在这里放什么?") 之类的操作。

是否有一个简单的正则表达式可以完成此任务?

编辑:我一直在审查我查看过的Regex Tutorial30 Minute Regex Tutorial

最佳答案

在这种情况下,我可能会使用 overload带有 MatchEvaluator 的 Regex.replace 。这允许您传递一个接受 Match 表达式并返回替换字符串的函数。

这是一个使用它的示例,它将与您的所有示例相匹配。我还将您的字符串嵌入到文件名中,以显示它们如何在文件名中替换(这似乎是您的目标)。

我在这里为 MatchEvaluator 使用了 lambda 表达式。如果你想要更复杂的逻辑,你可以 use a method on your class

我使用了两种正则表达式:一种用于匹配唯一的数字大小写,另一种用于匹配其他所有内容。我经常发现使用多个简单的正则表达式比尝试使用一个复杂的正则表达式更易于维护。

编辑:更新为使用正则表达式的优先级列表来尝试。在列表中找到第一个匹配项后它将停止检查

您必须确定要以什么顺序使用哪些规则(正则表达式)来适合您的数据。

string[] filenames = {
"1000 Ways to Die S01E01 Life Will Kill You",
"somefile1x01description.ext",
"sometext01x01description.ext",
"sometext101description.ext",
"sometextS01Edescription.ext",
"sometextS01 Edescription.ext",
"sometextS1Edescription.ext",
"sometextS1 Edescription.ext",
"sometextS1xdescription.ext",
"24 S01xE01 12 AM"
};

string [] res = {
    @"[sS]?(?<season>\d{1,2})[ xXeE]+(?<episode>\d{1,2})", // Handles the cases where you have a delimiter and a digit on both sides, optional S
    @"[sS](?<season>\d{1,2})[ xXeE]+(?<episode>\d{0,2})", // Handles the cases where you have a delimiter, a required S, but optional episode number
    @"(?<season>\d{1,2})(?<episode>\d{2})"  // Handles the case where you just have a 3 or 4 digit number
};

MatchEvaluator reFunc = match => // Given a Regex Match object
// An expression that returns the replacement string
"S" + // Start with the S
match.Groups["season"].Value // get the season group
.PadLeft(2,'0') + // zero pad it
"xE" + // Add the E
(match.Groups["episode"].Value.Length > 0 ? // Is there an episode number?
match.Groups["episode"].Value.PadLeft(2,'0') : // If so, zero pad it
"01" // Otherwise assume episode 01
); // End replacement expression

foreach(string name in filenames)
{
    Console.WriteLine("Orig: {0}",name);
    string replaced = name;

    foreach (string re in res)
    {
        Console.WriteLine("Trying:" + re);
        if(Regex.IsMatch(name,re))
        {
            Console.WriteLine("Matched");
            replaced = Regex.Replace(name,re,reFunc);
            break;
        }
    }
    Console.WriteLine("Replaced: {0}\n\n",replaced);
}

输出:

Orig: 1000 Ways to Die S01E01 Life Will Kill You
Trying:[sS]?(?<season>\d{1,2})[ xXeE]+(?<episode>\d{1,2})
Matched
Replaced: 1000 Ways to Die S01xE01 Life Will Kill You


Orig: somefile1x01description.ext
Trying:[sS]?(?<season>\d{1,2})[ xXeE]+(?<episode>\d{1,2})
Matched
Replaced: somefileS01xE01description.ext


Orig: sometext01x01description.ext
Trying:[sS]?(?<season>\d{1,2})[ xXeE]+(?<episode>\d{1,2})
Matched
Replaced: sometextS01xE01description.ext


Orig: sometext101description.ext
Trying:[sS]?(?<season>\d{1,2})[ xXeE]+(?<episode>\d{1,2})
Trying:[sS](?<season>\d{1,2})[ xXeE]+(?<episode>\d{0,2})
Trying:(?<season>\d{1,2})(?<episode>\d{2})
Matched
Replaced: sometextS01xE01description.ext


Orig: sometextS01Edescription.ext
Trying:[sS]?(?<season>\d{1,2})[ xXeE]+(?<episode>\d{1,2})
Trying:[sS](?<season>\d{1,2})[ xXeE]+(?<episode>\d{0,2})
Matched
Replaced: sometextS01xE01description.ext


Orig: sometextS01 Edescription.ext
Trying:[sS]?(?<season>\d{1,2})[ xXeE]+(?<episode>\d{1,2})
Trying:[sS](?<season>\d{1,2})[ xXeE]+(?<episode>\d{0,2})
Matched
Replaced: sometextS01xE01description.ext


Orig: sometextS1Edescription.ext
Trying:[sS]?(?<season>\d{1,2})[ xXeE]+(?<episode>\d{1,2})
Trying:[sS](?<season>\d{1,2})[ xXeE]+(?<episode>\d{0,2})
Matched
Replaced: sometextS01xE01description.ext


Orig: sometextS1 Edescription.ext
Trying:[sS]?(?<season>\d{1,2})[ xXeE]+(?<episode>\d{1,2})
Trying:[sS](?<season>\d{1,2})[ xXeE]+(?<episode>\d{0,2})
Matched
Replaced: sometextS01xE01description.ext


Orig: sometextS1xdescription.ext
Trying:[sS]?(?<season>\d{1,2})[ xXeE]+(?<episode>\d{1,2})
Trying:[sS](?<season>\d{1,2})[ xXeE]+(?<episode>\d{0,2})
Matched
Replaced: sometextS01xE01description.ext


Orig: 24 S01xE01 12 AM
Trying:[sS]?(?<season>\d{1,2})[ xXeE]+(?<episode>\d{1,2})
Matched
Replaced: 24 S01xE01 12 AM

关于c# - 如何使用正则表达式替换字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19204238/

相关文章:

c# - 在构造函数中为显式实现的只读接口(interface)属性赋值

java - 如何在评估正则表达式时消除线程阻塞 - 灾难性回溯

javascript - 用于删除部分 URL 参数的正则表达式

java - EditText 到 String 到 double 转换及计算错误

c# - 为什么 HtmlAgilityPack for .NET Core 1.5.0.1 找不到 HtmlWeb?是否有已知的解决方法或正确/更好的方法来做到这一点?

c# - Windows 应用商店 CurrentApp.LoadListingInformationAsync() - 错误 0x801900cc

c# - 在 if 语句中使用 GetForegroundWindow 结果来检查用户的当前窗口

regex - 查找 HTML5 表单用于验证的正则表达式

python - 将字符串拆分为包含许多 char pro 项目的数组

java - 将概率分配给随机枚举对象