代码之家  ›  专栏  ›  技术社区  ›  David Conlisk

c regex查找和替换匹配文本的重用部分

  •  3
  • David Conlisk  · 技术社区  · 15 年前

    我需要对长文本字符串进行搜索和替换。我想找到所有断开链接的实例,如下所示:

    <a href="http://any.url.here/%7BlocalLink:1369%7D%7C%7CThank%20you%20for%20registering">broken link</a>
    

    然后修复它,使其看起来像这样:

    <a href="/{localLink:1369}" title="Thank you for registering">link</a>
    

    文本字段中可能有许多断开的链接。我的困难在于如何重用匹配的ID(在本例中是1369)。在内容中,这个ID会从一个链接更改为另一个链接,URL和链接文本也是如此。

    谢谢,

    戴维

    编辑:为了澄清这一点,我编写了C代码来运行数百个长文本字段来修复其中断开的链接。每个单独的文本字段都包含HTML,其中可以有任意数量的断开链接-regex需要找到所有这些链接,并用正确版本的链接替换它们。

    4 回复  |  直到 15 年前
        1
  •  2
  •   Tomalak    15 年前

    用一点盐就可以了,html和regex不能很好地配合使用:

    (<a\s+[^>]*href=")[^"%]*%7B(localLink:\d+)%7D%7C%7C([^"]*)("[^>]*>[^<]*</a>)
    

    当应用于您的输入并替换为

    $1/{$2}" title="$3$4
    

    生成以下内容:

    <a href="/{localLink:1369}" title="Thank%20you%20for%20registering">broken link</a>
    

    这与单独使用regex非常接近。您需要使用 MatchEvaluator delegate 从替换中删除URL编码。

        2
  •  2
  •   Lucero    15 年前

    我假设您已经分析了元素和属性。因此,要处理该URL,请使用如下内容:

        string url = "http://any.url.here/%7BlocalLink:1369%7D%7C%7CThank%20you%20for%20registering";
        Match match = Regex.Match(HttpUtility.UrlDecode(url), @"^http://[^/]+/\{(?<local>[^:]+):(?<id>\d+)\}\|\|(?<title>.*)$");
        if (match.Success) {
            Console.WriteLine(match.Groups["local"].Value);
            Console.WriteLine(match.Groups["id"].Value);
            Console.WriteLine(match.Groups["title"].Value);
        } else {
            Console.WriteLine("Not one of those URLs");
        }
    
        3
  •  2
  •   Richard    15 年前

    要在替换字符串中包含匹配项,请使用 $& .

    替换字符串中可以使用许多其他替换标记, see here for the list .

        4
  •  1
  •   David Conlisk    15 年前

    感谢大家的帮助。下面是我最后使用的:

    const string pattern = @"(<a\s+[^>""]*href="")[^""]+(localLink:\d+)(?:%7[DC])*([^""]+)(""[^>]*>[^<]*</a>)";
    // Create a match evaluator to replace the matched links with the correct markup
    var myEvaluator = new MatchEvaluator(FixLink);
    
    var strNewText = Regex.Replace(strText, pattern, myEvaluator, RegexOptions.IgnoreCase);
    
    internal static string FixLink(Match m)
        {
            var strUrl = m.ToString();
            const string namedPattern = @"(<a\s+[^>""]*href="")[^""]+(localLink:\d+)(?:%7[DC])*([^""]+)(""[^>]*>[^<]*</a>)";
            var regex = new Regex(namedPattern);
    
            //const string strReplace = @"$1/{$2}"" title=""$4";
            const string strReplace = @"$1/{$2}"" title=""$4";
    
            HttpContext.Current.Response.Write(String.Format("Replacing '{0}' with '{1}'", strUrl, regex.Replace(strUrl, strReplace)));
            return regex.Replace(strUrl, strReplace);
        }