Регулярное выражение для нахождения значения "href" ссылки
Мне нужен шаблон регулярного выражения для поиска ссылок на веб-страницы в HTML.
Сначала я использую @"(<a.*?>.*?</a>)"
для извлечения ссылок (<a>
), но я не могу извлечь из него href
.
Мои строки:
-
<a href="www.example.com/page.php?id=xxxx&name=yyyy" ....></a>
-
<a href="#" onclick="location.href='http://www.example.com/page.php?id=xxxx&name=yyyy'; return false;" ....></a>
-
<a href="#" onclick="location.href='https://www.example.com/page.php?id=xxxx&name=yyyy'; return false;" ....></a>
-
<a href="www.example.com/page.php/404" ....></a>
1, 2 и 3 действительны, и они мне нужны, но номер 4 для меня недействителен
(?
и =
существенно)
Спасибо всем, но мне не нужен синтаксический анализ <a>
. У меня есть список ссылок в формате href="abcdef"
.
Мне нужно получить href
ссылок и отфильтровать его, мои любимые URL должны содержать ?
и =
как page.php?id=5
Спасибо!
Ответы
Ответ 1
Я бы рекомендовал использовать парсер HTML по регулярному выражению, но все же здесь регулярное выражение, которое создаст группу захвата над значением атрибута href
для каждой ссылки. Он будет соответствовать использованию двойных или одинарных кавычек.
<a\s+(?:[^>]*?\s+)?href=(["'])(.*?)\1
Вы можете просмотреть полное объяснение этого регулярного выражения в здесь.
Детская площадка:
let rx = /<a\s+(?:[^>]*?\s+)?href=(["'])(.*?)\1/,
textToMatchInput = document.querySelector('[name=textToMatch]');
document.querySelector('button').addEventListener('click', function () {
console.log(textToMatchInput.value.match(rx));
});
<label>
Text to match:
<input type="text" name="textToMatch" value='<a href="google.com"'>
<button>Match</button>
</label>
Ответ 2
Использование regex
для разбора html не рекомендуется
regex
используется для регулярно встречающихся шаблонов. html
не является регулярным с его форматом (кроме xhtml
). Например, файлы html
действительны, даже если вы не имеют closing tag
! Это может сломать ваш код.
Используйте синтаксический анализатор html, например htmlagilitypack
Вы можете использовать этот код для извлечения всех href's
в теге привязки с помощью HtmlAgilityPack
HtmlDocument doc = new HtmlDocument();
doc.Load(yourStream);
var hrefList = doc.DocumentNode.SelectNodes("//a")
.Select(p => p.GetAttributeValue("href", "not found"))
.ToList();
hrefList
содержит все href`s
Ответ 3
Попробуйте следующее:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
var res = Find(html);
}
public static List<LinkItem> Find(string file)
{
List<LinkItem> list = new List<LinkItem>();
// 1.
// Find all matches in file.
MatchCollection m1 = Regex.Matches(file, @"(<a.*?>.*?</a>)",
RegexOptions.Singleline);
// 2.
// Loop over each match.
foreach (Match m in m1)
{
string value = m.Groups[1].Value;
LinkItem i = new LinkItem();
// 3.
// Get href attribute.
Match m2 = Regex.Match(value, @"href=\""(.*?)\""",
RegexOptions.Singleline);
if (m2.Success)
{
i.Href = m2.Groups[1].Value;
}
// 4.
// Remove inner tags from text.
string t = Regex.Replace(value, @"\s*<.*?>\s*", "",
RegexOptions.Singleline);
i.Text = t;
list.Add(i);
}
return list;
}
public struct LinkItem
{
public string Href;
public string Text;
public override string ToString()
{
return Href + "\n\t" + Text;
}
}
}
Ввод:
string html = "<a href=\"www.aaa.xx/xx.zz?id=xxxx&name=xxxx\" ....></a> 2.<a href=\"http://www.aaa.xx/xx.zz?id=xxxx&name=xxxx\" ....></a> ";
Результат:
[0] = {www.aaa.xx/xx.zz?id=xxxx&name=xxxx}
[1] = {http://www.aaa.xx/xx.zz?id=xxxx&name=xxxx}
С# Скремблирование HTML-ссылок
Скребок HTML извлекает важные элементы страницы. Он имеет много юридических применений для веб-мастеров и разработчиков ASP.NET. С типом Regex и WebClient, мы реализуем экранирование экрана для HTML.
Edited
Еще один простой способ: вы можете использовать элемент управления web browser
для получения href
из тега a
, например: (см. мой пример)
public Form1()
{
InitializeComponent();
webBrowser1.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted);
}
private void Form1_Load(object sender, EventArgs e)
{
webBrowser1.DocumentText = "<a href=\"www.aaa.xx/xx.zz?id=xxxx&name=xxxx\" ....></a><a href=\"http://www.aaa.xx/xx.zz?id=xxxx&name=xxxx\" ....></a><a href=\"https://www.aaa.xx/xx.zz?id=xxxx&name=xxxx\" ....></a><a href=\"www.aaa.xx/xx.zz/xxx\" ....></a>";
}
void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
List<string> href = new List<string>();
foreach (HtmlElement el in webBrowser1.Document.GetElementsByTagName("a"))
{
href.Add(el.GetAttribute("href"));
}
}
Ответ 4
Попробуйте это регулярное выражение:
"href\\s*=\\s*(?:\"(?<1>[^\"]*)\"|(?<1>\\S+))"
Вы получите дополнительную помощь от обсуждений:
Регулярное выражение для извлечения URL из HTML-ссылки
и
Regex, чтобы получить ссылку в href. [Asp.net]
Надеюсь, что это будет полезно.
Ответ 5
Спасибо всем (особенно @plalx)
Я нахожу, что это довольно избыточно, принудительно применяет действительность атрибута href с таким сложным и загадочным шаблоном, в то время как простое выражение, например, <a\s+(?:[^>]*?\s+)?href="([^"]*)"
было бы достаточно для захвата всех URL-адресов. Если вы хотите убедиться, что они содержат хотя бы строку запроса, вы можете просто использовать <Б > <a\s+(?:[^>]*?\s+)?href="([^"]+\?[^"]+)"
Моя последняя строка регулярного выражения:
Сначала используйте одно из следующих действий:
st [email protected]"((www\.|https?|ftp|gopher|telnet|file|notes|ms-help):((//)|(\\\\))+ \w\d:#@%/;$()~_?\+-=\\\.&]*)";
st = "@<a href[^>]*>(.*?)</a>";
st = @"((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=\+\$,\w][email protected])?[A-Za-z0-9.-]+|(?:www.|[-;:&=\+\$,\w][email protected])[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)";
st = @"((?:(?:https?|ftp|gopher|telnet|file|notes|ms-help):(?://|\\\\)(?:www\.)?|www\.)[\w\d:#@%/;$()~_?\+,\-=\\.&]+)";
st = @"(?:(?:https?|ftp|gopher|telnet|file|notes|ms-help):(?://|\\\\)(?:www\.)?|www\.)";
st = @"(((https?|ftp|gopher|telnet|file|notes|ms-help):((//)|(\\\\))+)|(www\.)[\w\d:#@%/;$()~_?\+-=\\\.&]*)";
st = @"href=[""'](?<url>(http|https)://[^/]*?\.(com|org|net|gov))(/.*)?[""']";
st = @"(<a.*?>.*?</a>)";
st = @"(?:hrefs*=)(?:[s""']*)(?!#|mailto|location.|javascript|.*css|.*this.)(?.*?)(?:[s>""'])";
st = @"http://([\\w+?\\.\\w+])+([a-zA-Z0-9\\~\\!\\@\\#\\$\\%\\^\\&\\*\\(\\)_\\-\\=\\+\\\\\\/\\?\\.\\:\\;\\'\\,]*)?";
st = @"http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?";
st = @"(http|https)://([a-zA-Z0-9\\~\\!\\@\\#\\$\\%\\^\\&\\*\\(\\)_\\-\\=\\+\\\\\\/\\?\\.\\:\\;\\'\\,]*)?";
st = @"((http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?)";
st = @"http://([\\w+?\\.\\w+])+([a-zA-Z0-9\\~\\!\\@\\#\\$\\%\\^\\&\\*\\(\\)_\\-\\=\\+\\\\\\/\\?\\.\\:\\;\\'\\,]*)?";
st = @"http(s?)\:\/\/[0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*(:(0-9)*)*(\/?)([a-zA-Z0-9\-\.\?\,\'\/\\\+&%\$#_]*)?$";
st = @"(?<Protocol>\w+):\/\/(?<Domain>[\w.]+\/?)\S*";
мой выбор
@"(?<Protocol>\w+):\/\/(?<Domain>[\w.]+\/?)\S*"
Второй Используйте это:
st = "(.*)?(.*)=(.*)";
Проблема решена. Спасибо каждому:)
Ответ 6
HTMLDocument DOC = this.MySuperBrowser.Document as HTMLDocument;
public IHTMLAnchorElement imageElementHref;
imageElementHref = DOC.getElementById("idfirsticonhref") as IHTMLAnchorElement;
Просто попробуйте этот код
Ответ 7
Я придумал этот, поддерживающий метки привязки и изображения, и поддерживает одиночные и двойные кавычки.
<[a|img]+\\s+(?:[^>]*?\\s+)?[src|href]+=[\"']([^\"']*)['\"]
Итак,
<a href="/something.ext">click here</a>
Будет соответствовать:
Match 1: /something.ext
и
<a href='/something.ext'>click here</a>
Будет соответствовать:
Match 1: /something.ext
То же самое касается атрибутов img src