C#正则表达式查找和替换重用匹配部分的文本

3

我需要对长文本字符串进行搜索和替换。我想找到所有看起来像这样的损坏链接:

<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 - 正则表达式需要找到它们并用正确版本的链接替换它们。


你想匹配标签吗,还是只想将正则表达式应用于href属性的内容? - Lucero
我只想将第一个输出中的不正确的href属性分离出来,使其成为正确的href和title属性。我不介意如何实现 :) @tanascius - 我正在使用C#编写此代码。 - David Conlisk
我已经更正了我的正则表达式,请再试一次。 - Tomalak
4个回答

2

我假设您已经解析了元素和属性。因此,要处理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");
    }

2

请谨慎对待,HTML和正则表达式不太兼容:

(<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>

仅使用正则表达式,这已经是最接近的了。你需要使用MatchEvaluator委托来从替换中删除URL编码。


这非常接近 - 感谢您的帮助。有几个要点:
  1. 正则表达式也匹配正确的链接,但我不想要。
  2. 它替换了损坏的链接,但不完全正确,它给出了:<a href="http://url.still.here/%7BlocalLink:1369%7D" title="}||Thank you for registering">link</a> - 我需要删除 url.still.here 部分,以及标题属性中的 }||。
  3. 原始源代码是 HTML 编码的,但我需要替换后的文本使用 {localLink:1369} 而不是 %7BlocalLink:1369%7D。
你能帮忙吗?谢谢,大卫
- David Conlisk
我已经对我的正则表达式做出了一些更改,现在应该可以了。 - Tomalak

2

如果要在替换字符串中包含匹配项,您可以使用$&

还有许多其他的替换标记可用于替换字符串,请参见此处的列表


1

感谢大家的帮助。这是我最终使用的代码:

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);
    }

1
我认为你没有理解MatchEvaluator的用法。 - Tomalak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接