Полная замена
После некоторого затягивания с этим я выкладываю это решение. Используйте это или нет, это больше для моей текущей или будущей ссылки. Удивительно, но только часть tag-att-val покрывает почти все варианты использования. Тем не менее, регулярное выражение не рекомендуется для анализа HTML. Но если он используется, он должен быть достаточно точным.
Пример кода на C # можно найти здесь - http://ideone.com/TBxXm
Он был отлажен в VS2008 с использованием исходной страницы с CNN.com, затем рабочая копия вставлена в ideone для постоянной ссылки.
Вот легкомысленное регулярное выражение
<a
(?=\s)
# Optional preliminary att-vals (should prevent overruns)
(?:[^>"']|"[^"]*"|'[^']*')*?
# HREF, the attribute we're looking for
(?<=\s) href \s* =
# Quoted attr value (only)
# (?> \s* (['"]) (.*?) \1 )
# ---------------------------------------
# Or,
# Unquoted attr value (only)
# (?> (?!\s*['"]) \s* ([^\s>]*) (?=\s|>) )
# ---------------------------------------
# Or,
# Quoted/unquoted attr value (empty-unquoted value is allowed)
(?: (?> \s* (['"]) (?<URL>.*?) \1 )
| (?> (?!\s*['"]) \s* (?<URL>[^\s>]*) (?=\s|>) )
)
# Optional remaining att-vals
(?> (?:".*?"|'.*?'|[^>]?)+ )
# Non-terminated tag
(?<!/)
>
(?<TEXT>.*?)
</a \s*>
и здесь, как он существует в источнике C #
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string input = @"
<a asdf = href= >BLANK</a>
<a href= a""'tz target=_self >ATZ</a>
<a href=/2012/02/26/world/meast/iraq-missing-soldier-id/index.html?hpt=hp_bn1 target=""_self"">Last missing U.S. soldier in Iraq ID'd</a>
<a id=""weatherLocBtn"" href=""javascript:MainLocalObj.Weather.checkInput('weather',document.localAllLookupForm.inputField.value);""><span>Go</span></a>
<a href=""javascript:CNN_handleOverlay('profile_signin_overlay')"">Log in</a>
<a no='href' here> NOT FOUND </a>
<a this href= is_ok > OK </a>
";
string regex = @"
<a
(?=\s)
(?:[^>""']|""[^""]*""|'[^']*')*?
(?<=\s) href \s* =
(?: (?> \s* (['""]) (?<URL>.*?) \1 )
| (?> (?!\s*['""]) \s* (?<URL>[^\s>]*) (?=\s|>) )
)
(?> (?:"".*?""|'.*?'|[^>]?)+ )
(?<!/)
>
(?<TEXT>.*?)
</a \s*>
";
string output = Regex.Replace(input, regex, "${TEXT} [${URL}]",
RegexOptions.IgnoreCase |
RegexOptions.Singleline |
RegexOptions.IgnorePatternWhitespace);
Console.WriteLine(input+"\n------------\n");
Console.WriteLine(output);
}
}
}
с выводом
<a asdf = href= >BLANK</a>
<a href= a"'tz target=_self >ATZ</a>
<a href=/2012/02/26/world/meast/iraq-missing-soldier-id/index.html?hpt=hp_bn1 target="_self">Last missing U.S. soldier in Iraq ID'd</a>
<a id="weatherLocBtn" href="javascript:MainLocalObj.Weather.checkInput('weather',document.localAllLookupForm.inputField.value);"><span>Go</span></a>
<a href="javascript:CNN_handleOverlay('profile_signin_overlay')">Log in</a>
<a no='href' here> NOT FOUND </a>
<a this href= is_ok > OK </a>
------------
BLANK []
ATZ [a"'tz]
Last missing U.S. soldier in Iraq ID'd [/2012/02/26/world/meast/iraq-missing-soldier-id/index.html?hpt=hp_bn1]
<span>Go</span> [javascript:MainLocalObj.Weather.checkInput('weather',document.localAllLookupForm.inputField.value);]
Log in [javascript:CNN_handleOverlay('profile_signin_overlay')]
<a no='href' here> NOT FOUND </a>
OK [is_ok]
Ура!