首页 新闻 会员 周边 捐助

C# 中 Regex.Replace 的 MatchEvaluator 参数不支持 async 异步方法

0
悬赏园豆:30 [已解决问题] 浏览: 55次 解决于 2025-03-04 22:10

准备实现下面的正则表达式替换操作,替换时根据匹配到的博文标题,异步获取博文 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 参数不支持异步方法,请问如何解决这个问题?

dudu的主页 dudu | 高人七级 | 园豆:27686
提问于:2025-03-04 17:56
< > 人人可用的开源BI工具
分享
最佳答案
0

不抱希望地将搜索关键词“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 给出的这段漂亮代码漂亮地解决了实际问题!

dudu | 高人七级 |园豆:27686 | 2025-03-04 22:06
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册
Top