private static string handleTrailingParens(Match match)
{
// The first group is essentially a negative lookbehind -- if there's a < or a =", we don't touch this.
// We're not using a *real* lookbehind, because of links with in links, like <a href="http://web.archive.org/web/20121130000728/http://www.google.com/">
// With a real lookbehind, the full link would never be matched, and thus the http://www.google.com *would* be matched.
// With the simulated lookbehind, the full link *is* matched (just not handled, because of this early return), causing
// the google link to not be matched again.
if (match.Groups[1].Success)
return match.Value;
var protocol = match.Groups[2].Value;
var link = match.Groups[3].Value;
if (!link.EndsWith(")"))
return "<" + protocol + link + ">";
var level = 0;
foreach (Match c in Regex.Matches(link, "[()]"))
{
if (c.Value == "(")
{
if (level <= 0)
level = 1;
else
level++;
}
else
{
level--;
}
}
var tail = "";
if (level < 0)
{
link = Regex.Replace(link, @"\){1," + (-level) + "}$", m => { tail = m.Value; return ""; });
}
if (tail.Length > 0)
{
var lastChar = link[link.Length - 1];
if (!_endCharRegex.IsMatch(lastChar.ToString()))
{
tail = lastChar + tail;
link = link.Substring(0, link.Length - 1);
}
}
return "<" + protocol + link + ">" + tail;
}