准备实现下面的正则表达式替换操作,替换时根据匹配到的博文标题,异步获取博文 url,然后进行替换为包含标题与 url 的链接 html
public async Task<string> ConvertAsync(int blogId, string text)
{
return _postLinkPattern.Replace(text, async match =>
{
var title = match.Groups["title"].Value;
if (string.IsNullOrEmpty(title))
return match.Value;
var url = (await _postQuery.GetPostByTitle(blogId, title))?.Url;
if (string.IsNullOrEmpty(url))
return title;
return $"<a href=\"{url}\">{title}</a>";
});
}
实现时发现 Regex.Replace 的 MatchEvaluator 参数不支持异步方法,请问如何解决这个问题?
不抱希望地将搜索关键词“c# regex replace MatchEvaluator async”扔给 DeepSeek,DeepSeek 经过186秒的思考(下面的截图只是开头的3段思考文字)
然后 DeepSeek 在回答中给出了下面的代码:
using System.Text;
using System.Text.RegularExpressions;
public static class AsyncRegexReplacer
{
public static async Task<string> ReplaceAsync(string input, string pattern, Func<Match, Task<string>> evaluator, RegexOptions options = RegexOptions.None)
{
var matches = Regex.Matches(input, pattern, options);
var matchesList = matches.Cast<Match>().ToList();
// Asynchronously evaluate all replacements
var replacementTasks = matchesList.Select(match => evaluator(match)).ToList();
var replacements = await Task.WhenAll(replacementTasks).ConfigureAwait(false);
// Rebuild the string with replacements
var sb = new StringBuilder();
int currentIndex = 0;
int cumulativeDelta = 0;
for (int i = 0; i < matchesList.Count; i++)
{
Match match = matchesList[i];
string replacement = replacements[i];
int originalStart = match.Index;
int adjustedStart = originalStart + cumulativeDelta;
// Append text from current position to the start of the match
sb.Append(input, currentIndex, originalStart - currentIndex);
// Append the replacement
sb.Append(replacement);
// Update current position and delta
currentIndex = originalStart + match.Length;
cumulativeDelta += replacement.Length - match.Length;
}
// Append remaining text after the last match
sb.Append(input, currentIndex, input.Length - currentIndex);
return sb.ToString();
}
}
通过 DeepSeek 给出的这段漂亮代码漂亮地解决了实际问题!