Get "Title" attribute from html link using Regex
I have the following Regex to match all link tags in a page generated from our custom cms
<a\s+((?:(?:\w+\s*=\s*)(?:\w+|"[^"]*"|'[^']*'))*?\s*href\s*=\s*(?<url>\w+|"[^"]*"|'[^']*')(?:(?:\s+\w+\s*=\s*)(?:\w+|"[^"]*"|'[^']*'))*?)>.+?</a>
We use C # to loop through all matches of this and add an onclick event to each link (for tracking software) before displaying the page content. I need to parse a link and add a parameter to the onclick function which is the "link name".
I was going to change the regex to get the following subgroups
- Link title attribute
- If link contains image tag get alt text of image
- Link text
Then I can check if each subgroup matches on aqquire the corresponding link name.
How can I modify the above expression to do this, or can I achieve the same opinion using C # code?
a source to share
Regexes are fundamentally bad at parsing HTML (see Can you give some examples of why it is difficult to parse XML and HTML with regex? For what). You need an HTML parser. See Can you give an example of parsing HTML with your favorite parser? for examples using various parsers.
In particular, you may be interested in the HTMLAgilityPack answer .
a source to share
Try the following:
Regex reg = new Regex("<a[^>]*?title=\"([^\"]*?\"[^>]*?>");
Several mistakes:
- This will match the case sensitivity, you can adjust it
- The title attribute is expected to exist and be quoted
- Of course, if the title attribute doesn't exist, you probably don't want it to match?
To extract, use the group collection:
reg.Match("<a href=\"#\" title=\"Hello\">Howdy</a>").Groups[1].Value
a source to share
Thanks to Chaos. Owens for pointing me to the HtmlAgilityPack library, great. at the end I used it to sort out my problem as shown below. I would defiantly recommend this library to others.
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;
}
}
}
}
a source to share