web-dev-qa-db-fra.com

Regex sélectionner tout le texte entre les balises

Quel est le meilleur moyen de sélectionner tout le texte entre 2 balises - ex: le texte entre toutes les balises 'pre' de la page.

97
basheps

Vous pouvez utiliser "<pre>(.*?)</pre>" (remplacer pre par le texte de votre choix) et extraire le premier groupe (pour des instructions plus spécifiques, spécifiez une langue), mais cela suppose la notion simpliste selon laquelle vous disposez d'un code HTML très simple et valide.

Comme d'autres intervenants l'ont suggéré, si vous faites quelque chose de complexe, utilisez un analyseur HTML.

127
PyKing

La balise peut être complétée sur une autre ligne. C'est pourquoi \n doit être ajouté.

<PRE>(.|\n)*?<\/PRE>
103
zac

C'est ce que je voudrais utiliser.

(?<=(<pre>))(\w|\d|\n|[().,\-:;@#$%^&*\[\]"'+–/\/®°⁰!?{}|`~]| )+?(?=(</pre>))

En gros, ce qu'il fait est: 

(?<=(<pre>)) La sélection doit être précédée du tag <pre>

(\w|\d|\n|[().,\-:;@#$%^&*\[\]"'+–/\/®°⁰!?{}|~]| ) Ceci est juste une expression régulière que je veux appliquer. Dans ce cas, il sélectionne une lettre, un chiffre, un caractère de nouvelle ligne ou certains caractères spéciaux énumérés dans l'exemple entre crochets. Le caractère de pipe | signifie simplement "OU".

+? Plus états de caractères pour sélectionner un ou plusieurs des éléments ci-dessus - l'ordre n'a pas d'importance. Question mark modifie le comportement par défaut de "glouton" à "désagréable".

(?=(</pre>)) La sélection doit être ajoutée par la balise </pre>

 enter image description here

Selon votre cas d'utilisation, vous devrez peut-être ajouter des modificateurs tels que (i ou m).

  • i - insensible à la casse
  • m - recherche multiligne

Ici, j'ai effectué cette recherche dans Sublime Text afin de ne pas avoir à utiliser de modificateurs dans mes regex.

Javascript ne supporte pas lookbehind

L'exemple ci-dessus devrait fonctionner correctement avec des langages tels que PHP, Perl, Java .... .... Javascript ne supporte pas, mais nous devons oublier d'utiliser (?<=(<pre>)) et rechercher une solution de contournement. Peut-être simplement séparer les quatre premiers caractères de notre résultat pour chaque sélection, comme ici Le texte de correspondance de regex entre les balises

Consultez également la DOCUMENTATION JAVASCRIPT REGEX pour parenthèses non-capturantes

14
DevWL

utilisez le modèle ci-dessous pour obtenir le contenu entre les éléments. Remplacez [tag] par l'élément réel dont vous souhaitez extraire le contenu.

<[tag]>(.+?)</[tag]>

Parfois, les balises ont des attributs, tels que anchor tag ayant href, utilisez ensuite le modèle ci-dessous.

 <[tag][^>]*>(.+?)</[tag]>
9
Shravan Ramamurthy

Vous ne devriez pas essayer d’analyser le langage HTML avec des expressions rationnelles voir cette question et comment cela s’est avéré.

Dans les termes les plus simples, html n’est pas un langage courant, vous ne pouvez donc pas l’analyser complètement avec des expressions régulières.

Cela dit, vous pouvez analyser des sous-ensembles de HTML quand aucune balise similaire n’est imbriquée. Donc tant que rien entre et n'est pas cette balise elle-même, cela fonctionnera:

preg_match("/<([\w]+)[^>]*>(.*?)<\/\1>/", $subject, $matches);
$matches = array ( [0] => full matched string [1] => tag name [2] => tag content )

Une meilleure idée est d'utiliser un analyseur, tel que le DOMDocument natif, pour charger votre code HTML, puis sélectionnez votre balise et obtenez le code HTML interne qui pourrait ressembler à ceci:

$obj = new DOMDocument();
$obj -> load($html);
$obj -> getElementByTagName('el');
$value = $obj -> nodeValue();

Et puisqu'il s'agit d'un analyseur syntaxique approprié, il pourra gérer les balises imbriquées, etc.

6
sg3s

Cela semble être l'expression régulière la plus simple de tout ce que j'ai trouvé 

(?:<TAG>)([\s\S]*)(?:<\/TAG>)
  1. Exclure la balise d'ouverture (?:<TAG>) des correspondances
  2. Inclure tous les caractères blancs ou non blancs ([\s\S]*) dans les correspondances
  3. Exclure la balise de fermeture (?:<\/TAG>) des résultats
4
maqduni

Essaye ça....

(?<=\<any_tag\>)(\s*.*\s*)(?=\<\/any_tag\>)
3
Heriberto Rivera

Pour exclure les balises de délimitation:

"(?<=<pre>)(.*?)(?=</pre>)"
2
Jean-Simon Collard

var str = "Lorem ipsum <pre>text 1</pre> Lorem ipsum <pre>text 2</pre>";
    str.replace(/<pre>(.*?)<\/pre>/g, function(match, g1) { console.log(g1); });

Étant donné que la réponse acceptée est sans code javascript, ajoutez donc ceci:

1
Shishir Arora

Vous pouvez utiliser Pattern pattern = Pattern.compile( "[^<'tagname'/>]" );

0
Ambrish Rajput

preg_match_all(/<pre>([^>]*?)<\/pre>/,$content,$matches) cette expression rationnelle sélectionnera tout ce qui se trouve entre les balises. peu importe que ce soit dans la nouvelle ligne (travail avec multiline.

0
Krishna thakor

Pour plusieurs lignes:

<htmltag>(.+)((\s)+(.+))+</htmltag>
0
Dilip

J'utilise cette solution:

preg_match_all( '/<((?!<)(.|\n))*?\>/si',  $content, $new);
var_dump($new);
0
T.Todua