web-dev-qa-db-fra.com

expression régulière pour trouver la valeur 'href' d'un lien <a>

J'ai besoin d'un modèle d'expression régulière pour trouver des liens de page Web en HTML.

J'utilise d'abord @"(<a.*?>.*?</a>)" pour extraire les liens (<a>), mais je ne peux pas récupérer href à partir de cela.

Mes cordes sont:

  1. <a href="www.example.com/page.php?id=xxxx&name=yyyy" ....></a>
  2. <a href="http://www.example.com/page.php?id=xxxx&name=yyyy" ....></a>
  3. <a href="https://www.example.com/page.php?id=xxxx&name=yyyy" ....></a>
  4. <a href="www.example.com/page.php/404" ....></a>

1, 2 et 3 sont valides et j'en ai besoin, mais le numéro 4 n'est pas valide pour moi (? et = est essentiel)


Merci à tous, mais je n'ai pas besoin d'analyser <a>. J'ai une liste de liens dans href="abcdef" format.

Je dois récupérer href des liens et le filtrer, mes URL préférées doivent contenir ? et = comme page.php?id=5

Merci!

27
MrRolling

Je recommanderais d'utiliser un analyseur HTML sur une expression régulière, mais voici encore une expression régulière qui créera un groupe de capture sur la valeur de l'attribut href de chaque lien. Il correspondra à l'utilisation de guillemets doubles ou simples.

<a\s+(?:[^>]*?\s+)?href=(["'])(.*?)\1

Vous pouvez voir une explication complète de cette expression régulière à ici .

Aire de jeux d'extraits:

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>
59
plalx

L'utilisation de regex pour analyser le code HTML n'est pas recommandée

regex est utilisé pour les modèles qui se produisent régulièrement .html n'est pas régulier avec son format (sauf xhtml). Par exemple html les fichiers sont valides même si vous n'ont pas un closing tag! Cela pourrait casser votre code.

Utilisez un analyseur html comme htmlagilitypack

Vous pouvez utiliser ce code pour récupérer tous les href's dans la balise d'ancrage en utilisant HtmlAgilityPack

HtmlDocument doc = new HtmlDocument();
doc.Load(yourStream);

var hrefList = doc.DocumentNode.SelectNodes("//a")
                  .Select(p => p.GetAttributeValue("href", "not found"))
                  .ToList();

hrefList contient tous les href`s

10
Anirudha

Essaye ça :

 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;
            }
        }

    }  

Entrée:

  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> "; 

Résultat:

[0] = {www.aaa.xx/xx.zz?id=xxxx&name=xxxx}
[1] = {http://www.aaa.xx/xx.zz?id=xxxx&name=xxxx}

Liens HTML de grattage C #

Le scraping HTML extrait des éléments de page importants. Il a de nombreuses utilisations légales pour les webmasters et les développeurs ASP.NET. Avec le type Regex et WebClient, nous implémentons le grattage d'écran pour HTML.

Édité

Un autre moyen simple: vous pouvez utiliser un web browser contrôle pour obtenir href à partir de la balise a, comme ceci: (voir mon exemple)

 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"));
            }
        }
6
KF2

Merci à tous (spécialement @plalx)

Je trouve qu'il est assez exagéré d'appliquer la validité de l'attribut href avec un modèle aussi complexe et cryptique alors qu'une expression simple telle que
<a\s+(?:[^>]*?\s+)?href="([^"]*)"
suffirait pour capturer toutes les URL. Si vous voulez vous assurer qu'ils contiennent au moins une chaîne de requête, vous pouvez simplement utiliser
<a\s+(?:[^>]*?\s+)?href="([^"]+\?[^"]+)"


Ma dernière chaîne d'expression régulière:


Utilisez d'abord l'un de ces éléments:

st =@"((www\.|https?|ftp|Gopher|telnet|file|notes|ms-help):((//)|(\\\\))+ \w\d:#@%/;$()~_?\+-=\\\.&]*)";
st = "@<a href[^>]*>(.*?)</a>";
st = @"((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=\+\$,\w]+@)[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*";

mon choix est

@"(?<Protocol>\w+):\/\/(?<Domain>[\w.]+\/?)\S*"

Deuxième utilisation:

st = "(.*)?(.*)=(.*)";


Problème résolu. Merci tout le monde :)

4
MrRolling

Essayez cette expression régulière:

"href\\s*=\\s*(?:\"(?<1>[^\"]*)\"|(?<1>\\S+))"

Vous obtiendrez plus d'aide des discussions sur:

Expression régulière pour extraire l'URL d'un lien HTML

et

Regex pour obtenir le lien en href. [Asp.net]

J'espère que c'est utile.

3
Freelancer
 HTMLDocument DOC = this.MySuperBrowser.Document as HTMLDocument;
 public IHTMLAnchorElement imageElementHref;
 imageElementHref = DOC.getElementById("idfirsticonhref") as IHTMLAnchorElement;

Essayez simplement ce code

2
Joee

J'ai trouvé celui-ci, qui prend en charge les balises d'ancrage et d'image, et prend en charge les guillemets simples et doubles.

<[a|img]+\\s+(?:[^>]*?\\s+)?[src|href]+=[\"']([^\"']*)['\"]

Alors

<a href="/something.ext">click here</a>

Correspondra:

 Match 1: /something.ext

Et

<a href='/something.ext'>click here</a>

Correspondra:

 Match 1: /something.ext

Il en va de même pour les attributs img src

2
Base33