Подтвердить что ты не робот

Регулярное выражение для нахождения значения "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

Спасибо!

4b9b3361

Ответ 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"));
            }
        }

Ответ 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\\~\\!\\@\\#\\$\\%\\^\\&amp;\\*\\(\\)_\\-\\=\\+\\\\\\/\\?\\.\\:\\;\\'\\,]*)?";
st = @"http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?";
st = @"(http|https)://([a-zA-Z0-9\\~\\!\\@\\#\\$\\%\\^\\&amp;\\*\\(\\)_\\-\\=\\+\\\\\\/\\?\\.\\:\\;\\'\\,]*)?";
st = @"((http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&amp;:/~\+#]*[\w\-\@?^=%&amp;/~\+#])?)";
st = @"http://([\\w+?\\.\\w+])+([a-zA-Z0-9\\~\\!\\@\\#\\$\\%\\^\\&amp;\\*\\(\\)_\\-\\=\\+\\\\\\/\\?\\.\\:\\;\\'\\,]*)?";
st = @"http(s?)\:\/\/[0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*(:(0-9)*)*(\/?)([a-zA-Z0-9\-\.\?\,\'\/\\\+&amp;%\$#_]*)?$";
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