正则表达式将多个组替换为通配符
本文关键字:替换 通配符 正则表达式 | 更新日期: 2023-09-27 18:37:25
当我们不使用通配符时,我找到了答案。所以问题是 - 如何通过正则表达式执行多次替换。这段代码显示了我想做什么
internal class Program
{
private static void Main(string[] args)
{
var rules = new Dictionary<string, string>
{
{@"F'S+", "Replace 1"},
{@"'S+z", "Replace 2"},
};
string s = "Foo bar baz";
string result = ProcessText(s, rules);
Console.WriteLine(result);
}
private static string ProcessText(string input, Dictionary<string, string> rules)
{
string[] patterns = rules.Keys.ToArray();
string pattern = string.Join("|", patterns);
return Regex.Replace(input, pattern, match =>
{
int index = GetMatchIndex(match);
return rules[patterns[index]];
});
}
private static int GetMatchIndex(Match match)
{
int i = 0;
foreach (Match g in match.Groups)
{
if (g.Success)
return i;
i++;
}
throw new Exception("Never throws");
}
}
但match.Groups.Count
始终为 1。
我正在寻找最快的选择。也许,它不应该使用正则表达式。
我不
明白你为什么要连接模式,然后在数组中执行这么多搜索。
你不能像这样单独应用每个模式吗?
var rules = new Dictionary<string, string>
{
{@"F'S+", "Replace 1"},
{@"'S+z", "Replace 2"},
};
string s = "Foo bar baz";
var result = rules.Aggregate(s, (seed, rule) => Regex.Replace(seed, rule.Key, m => rule.Value));
编辑
您的match.Groups.Count
始终为 1,因为匹配项中未定义任何组,并且值是 MSDN 上所述的整个匹配字符串。换句话说,您的GetMatchIndex
方法不执行任何操作。
您可以尝试将模式转换为命名组,如下所示:
var patterns = rules.Select((kvp, index) => new
{
Key = String.Format("(?<{0}>{1})", index, kvp.Key),
Value = kvp.Value
};
有了这个数组,GetMatchIndex
方法中,您只需将组名解析为匹配模式的索引:
private static int GetMatchIndex(Regex regex, Match match)
{
foreach(var name in regex.GetGroupNames())
{
var group = match.Groups[name];
if(group.Success)
return int.Parse(name); //group name is a number
}
return -1;
}
现在,您可以像这样使用它:
var pattern = String.Join("|", patterns.Select(x => x.Key));
var regex = new Regex(pattern);
return regex.Replace(input, pattern, m =>
{
var index = GetMatchIndex(regex, m);
return patterns[index].Value;
});
让它(可能的方式)更快地提取
var keyArray = rules.Keys.ToArray()
在以下情况下使用它之前:
return Regex.Replace(input, pattern, match =>
{
int index = GetMatchIndex(match);
return rules[keyArray[index]];
});