使用Regex从html链接获取“标题”属性

时间:2009-05-12 15:32:50

标签: c# .net html regex

我有以下Regex来匹配从我们的自定义cms生成的页面上的所有链接标记

<a\s+((?:(?:\w+\s*=\s*)(?:\w+|"[^"]*"|'[^']*'))*?\s*href\s*=\s*(?<url>\w+|"[^"]*"|'[^']*')(?:(?:\s+\w+\s*=\s*)(?:\w+|"[^"]*"|'[^']*'))*?)>.+?</a>

我们使用c#循环遍历所有匹配项,并在呈现页面内容之前为每个链接添加onclick事件(用于跟踪软件)。 我需要解析链接并向onclick函数添加一个参数,即“链接名称”。

我打算修改正则表达式以获得以下子组

  • 链接的标题属性
  • 如果链接包含图片标记get 图像的替代文字
  • 链接的文字

然后,我可以检查每个子组的匹配,以获取链接的相关名称。

我如何修改上述正则表达式来执行此操作,还是可以使用c#代码实现相同的想法?

3 个答案:

答案 0 :(得分:6)

正则表达式在解析HTML方面根本不好(请参阅Can you provide some examples of why it is hard to parse XML and HTML with a regex?了解原因)。你需要的是一个HTML解析器。有关使用各种解析器的示例,请参阅Can you provide an example of parsing HTML with your favorite parser?

特别是您可能对HTMLAgilityPack answer感兴趣。

答案 1 :(得分:2)

试试这个:

Regex reg = new Regex("<a[^>]*?title=\"([^\"]*?\"[^>]*?>");

一些问题:

  • 这将匹配区分大小写,您可能需要调整
  • 这期望title属性既存在又被引用
    • 当然,如果title属性不存在,你可能还不想要匹配?

要提取,请使用groups集合:

reg.Match("<a href=\"#\" title=\"Hello\">Howdy</a>").Groups[1].Value

答案 2 :(得分:0)

感谢Chaos。欧文斯指出我的HtmlAgilityPack库很棒。最后我用它来解决我的问题,如下所示。 我会挑衅地向其他人推荐这个库。

   HtmlDocument htmldoc = new HtmlDocument();
    htmldoc.LoadHtml(content);
    HtmlNodeCollection linkNodes = htmldoc.DocumentNode.SelectNodes("//a[@href]");
    if (linkNodes != null)
    {
        foreach (HtmlNode linkNode in linkNodes)
        {
            string linkTitle = linkNode.GetAttributeValue("title", string.Empty);
            //If no title attribute exists check for an image alt tag
            if (linkTitle == string.Empty)
            {
                HtmlNode imageNode = linkNode.SelectSingleNode("img[@alt]");
                if (imageNode != null)
                {
                    linkTitle = imageNode.GetAttributeValue("alt", string.Empty);
                }
            }
            //If no image alt tag check for span with text
            if (linkTitle == string.Empty)
            {
                HtmlNode spanNode = linkNode.SelectSingleNode("span");
                if (spanNode != null)
                {
                    linkTitle = spanNode.InnerText;
                }
            }

            if (linkTitle == string.Empty)
            {
                if (!linkNode.HasChildNodes)
                {
                    linkTitle = linkNode.InnerText;
                }
            }

        }
    }