替换文本中的锚点/链接

Posted

技术标签:

【中文标题】替换文本中的锚点/链接【英文标题】:Replacing anchor/link in text 【发布时间】:2019-04-12 21:07:28 【问题描述】:

我在我的函数中执行查找/替换类型的操作时遇到问题,我正在从文章中提取 anchor 并将其替换为这种格式:[链接锚点]链接和锚点将是动态的,所以我无法对值进行硬编码,到目前为止我所拥有的是:

    public static string GetAndFixAnchor(string articleBody, string articleWikiCheck) 
        string theString = string.Empty;
        switch (articleWikiCheck) 
            case "id|wpTextbox1":
                StringBuilder newhtml = new StringBuilder(articleBody);
                Regex r = new Regex(@"\<a href=\""([^\""]+)\"">([^<]+)");
                string final = string.Empty;
                foreach (var match in r.Matches(theString).Cast<Match>().OrderByDescending(m => m.Index))
                
                    string text = match.Groups[2].Value;
                    string newHref = "[" + match.Groups[1].Index + " " + match.Groups[1].Index + "]";
                    newHtml.Remove(match.Groups[1].Index, match.Groups[1].Length);
                    newHtml.Insert(match.Groups[1].Index, newHref);
                
                theString = newHtml.ToString();
                break;
            default:
                theString = articleBody;
            break;
        
        Helpers.ReturnMessage(theString);
        return theString;
    

目前,它只返回文章原来的样子,使用传统的锚文本格式:anchor

谁能看到我做错了什么?

问候

【问题讨论】:

您想替换整个标签,还是只替换“href”属性的内容?不清楚 理想情况下,整个标签,换掉传统的锚格式:[link anchorText] 是目标。 为什么是正则表达式?可以使用AngleSharp、HtmlAgilityPack等HtmlParser轻松完成。 @colinreedy674 我之所以问,是因为您的组似乎是针对标记的位,这就是您用来设置删除和插入索引的方法。顺便说一句,您可能想使用“替换”而不是删除后跟替换。或者如 Frustrated 所说,使用 DOM 解析库。 你的case "id|wpTextbox1": 会触发吗?请检查。其余的可以通过Regex.Replace 轻松修复。 【参考方案1】:

如果你的输入是 HTML,你应该考虑使用相应的解析器,HtmlAgilityPack 真的很有帮助。

至于目前的代码,它看起来太冗长了。您可以使用单个Regex.Replace 一次性执行搜索和替换:

public static string GetAndFixAnchor(string articleBody, string articleWikiCheck) 
    if (articleWikiCheck == "id|wpTextbox1")
    
        return Regex.Replace(articleBody, @"<a\s+href=""([^""]+)"">([^<]+)", "[$1 $2]");
    
    else
    
        // Helpers.ReturnMessage(articleBody); // Uncomment if it is necessary
        return articleBody;
    

请参阅regex demo。

&lt;a\s+href="([^"]+)"&gt;([^&lt;]+) 正则表达式匹配 &lt;a、1 个或多个空格、href=",然后将除 " 之外的任何一个或多个字符捕获到第 1 组,然后匹配 "&gt;,然后将任何字符捕获到第 2 组除了&lt;之外的一个或多个字符。

[$1 $2] 替换将匹配的文本替换为 [、第 1 组内容、空格、第 2 组内容和 ]

【讨论】:

【参考方案2】:

更新(更正正则表达式以支持空格和新行)


你可以试试这个表达方式

Regex r = new Regex(@"<[\s\n]*a[\s\n]*(([^\s]+\s*[ ]*=*[ ]*[\s|\n*]*('|"").*\3)[\s\n]*)*href[ ]*=[ ]*('|"")(?<link>.*)\4[.\n]*>(?<anchor>[\s\S]*?)[\s\n]*<\/[\s\n]*a>");

它会匹配你的锚点,即使它们被分成多行。之所以这么长,是因为它支持标签和值之间的空格,而C#不支持子程序,所以这部分[\s\n]*不得不重复多次。

您可以在dotnetfiddle 看到一个工作示例 您可以像这样在示例中使用它。

public static string GetAndFixAnchor(string articleBody, string articleWikiCheck) 
    if (articleWikiCheck == "id|wpTextbox1")
    
        return Regex.Replace(articleBody, 
                             @"<[\s\n]*a[\s\n]*(([^\s]+\s*[ ]*=*[ ]*[\s|\n*]*('|"").*\3)[\s\n]*)*href[ ]*=[ ]*('|"")(?<link>.*)\4[.\n]*>(?<anchor>[\s\S]*?)[\s\n]*<\/[\s\n]*a>",
                             "[$link $anchor]");
    
    else
    
        return articleBody;
    
   

【讨论】:

以上是关于替换文本中的锚点/链接的主要内容,如果未能解决你的问题,请参考以下文章

React SPA 中的锚点或按钮?

HTML中的锚点以及锚点的设置与应用

用javascript 怎样清空访问过的锚点记录

跨页面的锚点链接

JavaFX WebView:使用loadContent()链接到文档中的锚点不起作用

带有 id 链接的锚点的技术术语是啥?