web-dev-qa-db-fra.com

Utiliser regex pour obtenir du texte entre plusieurs balises HTML

Avec regex, je veux pouvoir obtenir le texte entre plusieurs balises DIV. Par exemple, les éléments suivants:

<div>first html tag</div>
<div>another tag</div>

Serait sortie:

first html tag
another tag

Le motif regex que j'utilise correspond uniquement à ma dernière balise div et manque la première ..__

    static void Main(string[] args)
    {
        string input = "<div>This is a test</div><div class=\"something\">This is ANOTHER test</div>";
        string pattern = "(<div.*>)(.*)(<\\/div>)";

        MatchCollection matches = Regex.Matches(input, pattern);
        Console.WriteLine("Matches found: {0}", matches.Count);

        if (matches.Count > 0)
            foreach (Match m in matches)
                Console.WriteLine("Inner DIV: {0}", m.Groups[2]);

        Console.ReadLine();
    }

Sortie:

Résultats trouvés: 1

Inner DIV: Ceci est un autre test

8
ben

Remplacez votre motif par une correspondance non gourmande

static void Main(string[] args)
{
    string input = "<div>This is a test</div><div class=\"something\">This is ANOTHER test</div>";
    string pattern = "<div.*?>(.*?)<\\/div>";

    MatchCollection matches = Regex.Matches(input, pattern);
    Console.WriteLine("Matches found: {0}", matches.Count);

    if (matches.Count > 0)
        foreach (Match m in matches)
            Console.WriteLine("Inner DIV: {0}", m.Groups[1]);

    Console.ReadLine();
}
13
coolmine

Comme d'autres personnes n'ont pas mentionné HTML tags with attributes, voici ma solution pour y remédier:

// <TAG(.*?)>(.*?)</TAG>
// Example
var regex = new System.Text.RegularExpressions.Regex("<h1(.*?)>(.*?)</h1>");
var m = regex.Match("Hello <h1 style='color: red;'>World</h1> !!");
Console.Write(m.Groups[2].Value); // will print -> World
7
Mehdi Dehghani

Tout d’abord, rappelez-vous que dans le fichier HTML, vous aurez un nouveau symbole de ligne ("\ n"), que vous n’avez pas inclus dans la chaîne que vous utilisez pour vérifier votre expression régulière.

Deuxièmement, en prenant regex:

((<div.*>)(.*)(<\\/div>))+ //This Regex will look for any amount of div tags, but it must see at least one div tag.

((<div.*>)(.*)(<\\/div>))* //This regex will look for any amount of div tags, and it will not complain if there are no results at all.

C'est également un bon endroit pour rechercher ce type d'informations:

http://www.regular-expressions.info/reference.html

http://www.regular-expressions.info/refadv.html

Mayman

1
Mayman

Avez-vous examiné le Html Agility Pack (voir https://stackoverflow.com/a/857926/618649 )?

CsQuery semble également très utile (utilisez la syntaxe de style de sélecteur CSS pour obtenir les éléments). Voir https://stackoverflow.com/a/11090816/618649 .

CsQuery est fondamentalement destiné à être "jQuery for C #", ce qui correspond à peu près aux critères de recherche exacts utilisés auparavant.

Si vous pouviez le faire dans un navigateur Web, vous pourriez facilement utiliser jQuery, en utilisant une syntaxe similaire à $("div").each(function(idx){ alert( idx + ": " + $(this).text()); } (vous êtes le seul à pouvoir évidemment afficher le résultat dans le journal ou l'écran, ou faire un appel de service Web avec celui-ci, faire avec elle).

1
Craig

Je pense que ce code devrait fonctionner:

string htmlSource = "<div>first html tag</div><div>another tag</div>";
string pattern = @"<div[^>]*?>(.*?)</div>";
MatchCollection matches = Regex.Matches(htmlSource, pattern, RegexOptions.IgnoreCase | RegexOptions.Singleline);
ArrayList l = new ArrayList();
foreach (Match match in matches)
 {
   l.Add(match.Groups[1].Value);
 }
1
Tri Nguyen Dung

La version courte est que vous ne pouvez pas le faire correctement dans toutes les situations. Il y aura toujours des cas de code HTML valide pour lesquels une expression régulière ne parviendra pas à extraire les informations souhaitées.

La raison en est que HTML est une grammaire sans contexte qui est une classe plus complexe qu'une expression régulière.

Voici un exemple - et si vous avez plusieurs div empilés?

<div><div>stuff</div><div>stuff2</div></div>

Les regexes listées comme autres réponses vont récupérer:

<div><div>stuff</div>
<div>stuff</div>
<div>stuff</div><div>stuff2</div>
<div>stuff</div><div>stuff2</div></div>
<div>stuff2</div>
<div>stuff2</div></div>

parce que c’est ce que font les expressions régulières quand ils essaient d’analyser HTML.

Vous ne pouvez pas écrire une expression régulière qui comprend comment interpréter tous les cas, car les expressions régulières sont incapables de le faire. Si vous traitez avec un ensemble très spécifique de HTML contraint, cela peut être possible, mais gardez cela à l'esprit.

Plus d'informations: https://stackoverflow.com/a/1732454/2022565

0
Tom Jacques