我有一些想法如何在 string.replace 方法中使用正则表达式来“匹配”值,但实际上不知道如何操作它们。我尝试通过查找文件名中的以下常见模式并用更标准化的命名约定替换它们来重命名文件。
这是我尝试替换的示例:
“1x01” “01x01” “101” “S01E” “S01E” “S1E” “S1E” “S1x”
并将其替换为 S01xE01,其中 S01 代表第 1 季,E01 代表第 1 集,因此数值当然会有变化...我的想法是正则表达式,但在浏览下一个之后,我不会找到特定的足够的例子来帮助我。
我陷入困境的部分原因是即使我找到了匹配的表达式,我也不知道如何进行替换。例如,如果我执行 string.replace("S\d*E\d*","我在这里放什么?") 之类的操作。
是否有一个简单的正则表达式可以完成此任务?
编辑:我一直在审查我查看过的Regex Tutorial和 30 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/