Question Les tags ouverts RegEx correspondent aux tags autonomes XHTML


Je dois faire correspondre toutes ces balises d'ouverture:

<p>
<a href="foo">

Mais pas ceux-ci:

<br />
<hr class="foo" />

Je suis venu avec cela et je voulais m'assurer que je l'ai bien fait. Je capture seulement le a-z.

<([a-z]+) *[^/]*?>

Je crois que ça dit:

  • Trouver un moins que, alors
  • Trouvez (et capturez) a-z une ou plusieurs fois, puis
  • Trouvez zéro ou plusieurs espaces, puis
  • Trouver n'importe quel caractère zéro ou plusieurs fois, gourmand, sauf /, puis
  • Trouver un plus grand que

Est-ce que j'ai ce droit? Et plus important encore, qu'en pensez-vous?


1324
2017-09-27 04:01


origine


Réponses:


Vous ne pouvez pas analyser [X] HTML avec regex. Parce que HTML ne peut pas être analysé par regex. Regex n'est pas un outil qui peut être utilisé pour analyser correctement HTML. Comme j'ai déjà répondu tant de fois aux questions HTML et regex, l'utilisation de regex ne vous permettra pas de consommer du HTML. Les expressions régulières sont un outil insuffisamment sophistiqué pour comprendre les constructions employées par HTML. HTML n'est pas un langage régulier et ne peut donc pas être analysé par des expressions régulières. Les requêtes Regex ne sont pas équipées pour décomposer le HTML en ses parties significatives. tant de fois, mais ça ne m'arrive pas. Même les expressions rationnelles irrégulières améliorées utilisées par Perl ne sont pas à la hauteur de l'analyse de HTML. Tu ne me feras jamais craquer. HTML est un langage suffisamment complexe pour qu'il ne puisse pas être analysé par des expressions régulières. Même Jon Skeet ne peut pas analyser HTML en utilisant des expressions régulières. Chaque fois que vous essayez d'analyser HTML avec des expressions régulières, l'enfant impie pleure le sang des vierges, et les pirates russes pwn votre webapp. Parsing HTML avec regex convoque les âmes corrompues dans le royaume des vivants. HTML et regex vont ensemble comme l'amour, le mariage et l'infanticide rituel. Le <center> ne peut pas tenir, c'est trop tard. La force de regex et HTML ensemble dans le même espace conceptuel détruira votre esprit comme autant de mastic aqueux. Si vous parsiez HTML avec regex vous cédez à eux et à leurs manières blasphématoires qui nous condamnent tous à un travail inhumain pour Celui dont le Nom ne peut pas être exprimé dans le Plan Multilingue de Base, il vient. HTML-plus-regexp va liquéfier les nerfs du sensible tandis que vous observez, votre psyché se flétrissant dans l'assaut de l'horreur. Les parseurs HTML basés sur Rege̿̔̉x sont le cancer qui tue StackOverflow il est trop tard, il est trop tard, nous ne pouvons pas être sauvés la trangession d'un chi͡ld assure que regex consommera tous les tissus vivants (sauf pour le HTML qui ne peut pas, comme prophétisé précédemment) cher seigneur nous aider comment quelqu'un peut-il survivre à ce fléau l'utilisation de regex pour analyser HTML a condamné l'humanité à une éternité de torture et de trous de sécurité en utilisant regex comme un outil pour traiter le HTML établit un breach entre ce monde et le domaine redouté des entités c͒ͪo͛ͫrrupt (comme les entités SGML, mais plus corrompu) un simple coup d'oeilse du monde de regex parseurs pour HTML va insTransporte aussi un pla conscience de rogrammer into a world de cris incessants, il vient, le sl pestilentithy regex-infection wilJe dévore ton HTML analyseur, l'application et l'existence pour tous les temps comme Visual Basic seulement pire il vient il comes ne pas fiGht he com̡e̶s, ̕h̵iS radiańcé de s un̨ho͞lyStro҉ying tout enli̍̈̈ghtenment, balises HTML lea͠ki̧n͘g fr̶ǫm ̡yo ͟ur oeil͢s̸ ̛l̕ik͏e liqUid pain, la chanson de re̸gular exp ression analyse ExtiNoyer les voix de mortal homme du spIci je peux le voir pouvez-vous voir ͚̖͔̙î̩t͎̩͔̋ il est beau til final snuffing of le mensonges of Man TOUT EST LOŚ͖̩͇̗̪̏̈T ALL I S LOSTe pon̷y il vients il c̶̮omes il comois til ichou imprégneres all MON FACE MON VISAGE ᵒh dieu no NO NO̼O O NΘ arrête til un * ̶͑̾̾ ̅ͫ͏̙̤g͇̫͛͆̾ͫ̑͆l͖͉̗̩̳̟̍ͫͥͨe̠̅s ͎a̧͈͖r̽̾̈́͒͑e nOt rè̑ͧ̌aͨl̘̝̙ͤ̾̆ ZA̡͊͠͝LGΌ ISͮ҉̯͈͕̹̘ TO͇̹̺Ɲ̴ȳ̳ TH͇̹̺Ɲ̴ȳ̳Ë͖̉ ͠P̯͍̭O̚ N̐Y̡ H̸̡̪̯ͨ͊̽̅̾Ȩ̬̩̾͛ͪ̈͘ ̶̧̨̹̭̯ͧ̾ͬC̷̙̝͖ͭ̏ͥͮ͟Oͮ͏̮̪̝͍M̖͊̒ͪͩͬ̚̚͜Ȇ̴̟̟͙̞ͩ͌͝S̨̥̫͎̭ͯ̿̔


Avez-vous essayé d'utiliser un analyseur XML à la place?


Note du modérateur

Ce message est verrouillé pour empêcher les modifications inappropriées de son contenu. Le post ressemble exactement à ce qu'il est supposé être - il n'y a pas de problèmes avec son contenu. S'il vous plaît ne le signalez pas pour notre attention.


4422



Alors qu'il est vrai que demander des regexes pour analyser arbitraire HTML est comme demander à un débutant d'écrire un système d'exploitation, il est parfois approprié d'analyser un limité, connu ensemble de HTML.

Si vous disposez d'un petit ensemble de pages HTML dont vous souhaitez extraire des données et les insérer dans une base de données, les expressions régulières peuvent fonctionner correctement. Par exemple, j'ai récemment voulu obtenir les noms, les partis et les districts des représentants fédéraux australiens, que j'ai obtenus sur le site Web du Parlement. C'était un travail limité et ponctuel.

Regexes a très bien fonctionné pour moi et a été très rapide à mettre en place.


2915



Je pense que la faille ici est que le HTML est un Chomsky Type 2 grammaire (grammaire sans contexte) et RegEx est un Chomsky Type 3 grammaire (grammaire régulière). Comme une grammaire de type 2 est fondamentalement plus complexe qu'une grammaire de type 3 (voir La hiérarchie de Chomsky), vous ne pouvez pas faire ce travail. Mais beaucoup vont essayer, certains vont réclamer le succès et d'autres vont trouver la faute et vous gâcher totalement.


1799



N'écoute pas ces gars-là. Vous avez réellement pouvez analyser grammaires contextuelles avec regex si vous divisez la tâche en plus petits morceaux. Vous pouvez générer le modèle correct avec un script qui exécute chacun de ces éléments dans l'ordre:

  1. Résoudre le problème d'arrêt.
  2. Carré un cercle (simuler la règle "règle et la boussole" pour cela).
  3. Calculez le problème du vendeur ambulant dans O (log n). Il doit être rapide ou le générateur va se bloquer.
  4. Le modèle sera assez grand, alors assurez-vous d'avoir un algorithme qui compresse sans perte les données aléatoires.
  5. Presque là - il suffit de diviser le tout par zéro. Peasy facile.

Je n'ai pas encore compris la dernière partie, mais je sais que je me rapproche. Mon code continue de lancer CthulhuRlyehWgahnaglFhtagnExceptions dernièrement, donc je vais le porter sur VB 6 et utiliser On Error Resume Next. Je mettrai à jour avec le code une fois que j'explorerai cette étrange porte qui vient de s'ouvrir dans le mur. Hmm.

P.S. Pierre de Fermat a aussi compris comment le faire, mais la marge dans laquelle il écrivait n'était pas assez grande pour le code.


1167



Avertissement: utilisez un analyseur si vous avez l'option. Cela dit...

C'est la regex que j'utilise (!) Pour faire correspondre les balises HTML:

<(?:"[^"]*"['"]*|'[^']*'['"]*|[^'">])+>

Ce n'est peut-être pas parfait, mais j'ai couru ce code à travers un lot de HTML. Notez qu'il attrape même des choses étranges comme <a name="badgenerator"">, qui apparaissent sur le web.

Je suppose que pour ne pas faire correspondre les balises autonomes, vous souhaitez soit utiliser Kobi's look-behind négatif:

<(?:"[^"]*"['"]*|'[^']*'['"]*|[^'">])+(?<!/\s*)>

ou simplement combiner si et si non.

Pour les downvoters: C'est le code de travail d'un produit réel. Je doute que quiconque lit cette page aura l'impression qu'il est socialement acceptable d'utiliser des expressions rationnelles sur le HTML.

Caveat: Je dois noter que cette regex se décompose toujours en présence de blocs CDATA, de commentaires, d'éléments de script et de style. Les bonnes nouvelles sont, vous pouvez vous débarrasser de ceux qui utilisent une regex ...


1016



Il y a des gens qui vous diront que la Terre est ronde (ou peut-être que la Terre est un sphéroïde oblat s'ils veulent utiliser des mots étranges). Ils mentent.

Il y a des gens qui vous diront que les expressions régulières ne devraient pas être récursives. Ils vous limitent. Ils ont besoin de vous subjuguer, et ils le font en vous gardant dans l'ignorance.

Vous pouvez vivre dans leur réalité ou prendre la pilule rouge.

Comme Lord Marshal (est-il un parent de la classe Marshal .NET?), J'ai vu le Underverse Stack Based Regex-Verse et retourné avec pouvoirs connaissances que vous ne pouvez pas imaginer. Oui, je pense qu'il y avait un vieux ou deux qui les protégeait, mais ils regardaient le football à la télé, donc ce n'était pas difficile.

Je pense que le cas XML est assez simple. Le RegEx (dans la syntaxe .NET), déflaté et codé en base64 pour le rendre plus facile à comprendre par votre esprit faible, devrait être quelque chose comme ceci:

7L0HYBxJliUmL23Ke39K9UrX4HShCIBgEyTYkEAQ7MGIzeaS7B1pRyMpqyqBymVWZV1mFkDM7Z28
995777333nvvvfe6O51OJ/ff/z9cZmQBbPbOStrJniGAqsgfP358Hz8itn6Po9/3eIue3+Px7/3F
86enJ8+/fHn64ujx7/t7vFuUd/Dx65fHJ6dHW9/7fd/t7fy+73Ye0v+f0v+Pv//JnTvureM3b169
OP7i9Ogyr5uiWt746u+BBqc/8dXx86PP7tzU9mfQ9tWrL18d3UGnW/z7nZ9htH/y9NXrsy9fvPjq
i5/46ss3p4z+x3e8b452f9/x93a2HxIkH44PpgeFyPD6lMAEHUdbcn8ffTP9fdTrz/8rBPCe05Iv
p9WsWF788Obl9MXJl0/PXnwONLozY747+t7x9k9l2z/4vv4kqo1//993+/vf2kC5HtwNcxXH4aOf
LRw2z9/v8WEz2LTZcpaV1TL/4c3h66ex2Xv95vjF0+PnX744PbrOm59ZVhso5UHYME/dfj768H7e
Yy5uQUydDAH9+/4eR11wHbqdfPnFF6cv3ogq/V23t++4z4620A13cSzd7O1s/77rpw+ePft916c7
O/jj2bNnT7e/t/397//M9+ibA/7s6ZNnz76PP0/kT2rz/Ts/s/0NArvziYxVEZWxbm93xsrUfnlm
rASN7Hf93u/97vvf+2Lx/e89L7+/FSXiz4Bkd/hF5mVq9Yik7fcncft9350QCu+efkr/P6BfntEv
z+iX9c4eBrFz7wEwpB9P+d9n9MfuM3yzt7Nzss0/nuJfbra3e4BvZFR7z07pj3s7O7uWJM8eCkme
nuCPp88MfW6kDeH7+26PSTX8vu+ePAAiO4LVp4zIPWC1t7O/8/+pMX3rzo2KhL7+8s23T1/RhP0e
vyvm8HbsdmPXYDVhtpdnAzJ1k1jeufOtUAM8ffP06Zcnb36fl6dPXh2f/F6nRvruyHfMd9rgJp0Y
gvsRx/6/ZUzfCtX4e5hTndGzp5jQo9e/z+s3p1/czAUMlts+P3tz+uo4tISd745uJxvb3/v4ZlWs
mrjfd9SG/swGPD/6+nh+9MF4brTBRmh1Tl5+9eT52ckt5oR0xldPzp7GR8pfuXf5PWJv4nJIwvbH
W3c+GY3vPvrs9zj8Xb/147/n7/b7/+52DD2gsSH8zGDvH9+i9/fu/PftTfTXYf5hB+9H7P1BeG52
MTtu4S2cTAjDizevv3ry+vSNb8N+3+/1po2anj4/hZsGt3TY4GmjYbEKDJ62/pHB+3/LmL62wdsU
1J18+eINzTJr3dMvXr75fX7m+MXvY9XxF2e/9+nTgPu2bgwh5U0f7u/74y9Pnh6/OX4PlA2UlwTn
xenJG8L996VhbP3++PCrV68QkrjveITxr2TIt+lL+f3k22fPn/6I6f/fMqZvqXN/K4Xps6sazUGZ
GeQlar49xEvajzI35VRevDl78/sc/b7f6jkG8Va/x52N4L9lBe/kZSh1hr9fPj19+ebbR4AifyuY
12efv5CgGh9TroR6Pj2l748iYxYgN8Z7pr0HzRLg66FnRvcjUft/45i+pRP08vTV6TOe2N/9jv37
R9P0/5YxbXQDeK5E9R12XdDA/4zop+/9Ht/65PtsDVlBBUqko986WsDoWqvbPD2gH/T01DAC1NVn
3/uZ0feZ+T77fd/GVMkA4KjeMcg6RcvQLRl8HyPaWVStdv17PwHV0bOB9xUh7rfMp5Zu3icBJp25
D6f0NhayHyfI3HXHY6YYCw7Pz17fEFhQKzS6ZWChrX+kUf7fMqavHViEPPKjCf1/y5hukcyPTvjP
mHQCppRDN4nbVFPaT8+ekpV5/TP8g/79mVPo77PT1/LL7/MzL7548+XvdfritflFY00fxIsvSQPS
mvctdYZpbt7vxKRfj3018OvC/hEf/79lTBvM3debWj+b8KO0wP+3OeM2aYHumuCAGonmCrxw9cVX
X1C2d4P+uSU7eoBUMzI3/f9udjbYl/el04dI7s8fan8dWRjm6gFx+NrKeFP+WX0CxBdPT58df/X8
DaWLX53+xFdnr06f/szv++NnX7x8fnb6NAhIwsbPkPS7iSUQAFETvP2Tx8+/Og0Xt/yBvDn9vd/c
etno8S+81QKXptq/ffzKZFZ+4e/743e8zxino+8RX37/k595h5/H28+y7fPv490hQdJ349E+txB3
zPZ5J/jsR8bs/y1j2hh/2fkayOqEmYcej0cXUWMN7QrqBwjDrVZRfyQM3xjj/EgYvo4wfLTZrnVS
ebdKq0XSZJvzajKQDUv1/P3NwbEP7cN5+Odivv9/ysPfhHfkOP6b9Fl+91v7LD9aCvp/+Zi+7lLQ
j0zwNzYFP+/Y6r1NcFeDbfBIo8rug3zS3/3WPumPlN3/y8f0I2X3cz4FP+/Y6htSdr2I42fEuSPX
/ewpL4e9/n1evzn94hb+Plpw2+dnbyh79zx0CsPvbq0lb+UQ/h7xvqPq/Gc24PnR18fzVrp8I57d
mehj7ebk5VdPnp+d3GJOSP189eTsaXyk/JV7l98j4SAZgRxtf7x155PR+O6jz36Pw9/1Wz/+e/5u
v//vbsfQAxobws8M9v7xLXp/785/395ED4nO1wx5fsTeH4LnRva+eYY8rpZUBFb/j/jfm8XAvfEj
4/b/ljF1F9B/jx5PhAkp1nu/+y3n+kdZp/93jWmjJ/M11TG++VEG6puZn593PPejoOyHMQU/79jq
GwrKfpSB+tmcwZ93XPkjZffDmIKfd2z1DSm7bmCoPPmjBNT74XkrVf71I/Sf6wTU7XJA4RB+lIC6
mW1+xN5GWw1/683C5rnj/m364cmr45Pf6/SN9H4Us4LISn355vjN2ZcvtDGT6fHvapJcMISmxc0K
MAD4IyP6/5Yx/SwkP360FvD1VTH191mURr/HUY+2P3I9boPnz7Ju/pHrcWPnP3I9/r/L3sN0v52z
0fEgNrgbL8/Evfh9fw/q5Xf93u/97vvf+2Lx/e89L7+/Fe3iZ37f34P5h178kTfx/5YxfUs8vY26
7/d4/OWbb5++ogn7PX5XzOHtOP3GrsHmqobOVO/8Hh1Gk/TPl198QS6w+rLb23fcZ0fMaTfjsv29
7Zul7me2v0FgRoYVURnf9nZEkDD+H2VDf8hjeq8xff1s6GbButNLacEtefHm9VdPXp++CRTw7/v9
r6vW8b9eJ0+/PIHzs1HHdyKE/x9L4Y+s2f+PJPX/1dbsJn3wrY6wiqv85vjVm9Pnp+DgN8efM5va
j794+eb36Xz3mAf5+58+f3r68s230dRvJcxKn/l//oh3f+7H9K2O0r05PXf85s2rH83f/1vGdAvd
w+qBFqsoWvzspozD77EpXYeZ7yzdfxy0ec+l+8e/8FbR84+Wd78xbvn/qQQMz/J7L++GPB7N0MQa
2vTMBwjDrVI0PxKGb4xxfiQMX0cYPuq/Fbx2C1sU8yEF+F34iNsx1xOGa9t6l/yX70uqmxu+qBGm
AxlxWwVS11O97ULqlsFIUvUnT4/fHIuL//3f9/t9J39Y9m8W/Tuc296yUeX/b0PiHwUeP1801Y8C
j/9vz9+PAo8f+Vq35Jb/n0rAz7Kv9aPA40fC8P+RMf3sC8PP08DjR1L3DXHoj6SuIz/CCghZNZb8
fb/Hf/2+37tjvuBY9vu3jmRvxNeGgQAuaAF6Pwj8/+e66M8/7rwpRNj6uVwXZRl52k0n3FVl95Q+
+fz0KSu73/dtkGDYdvZgSP5uskadrtViRKyal2IKAiQfiW+FI+tET/9/Txj9SFf8SFf8rOuKzagx
+r/vD34mUADO1P4/AQAA//8=

Les options à définir sont RegexOptions.ExplicitCapture. Le groupe de capture que vous recherchez est ELEMENTNAME. Si le groupe de capture ERROR n'est pas vide alors il y avait une erreur d'analyse et le Regex s'est arrêté.

Si vous avez des problèmes de reconversion vers une expression rationnelle lisible par l'homme, cela devrait aider:

static string FromBase64(string str)
{
    byte[] byteArray = Convert.FromBase64String(str);

    using (var msIn = new MemoryStream(byteArray))
    using (var msOut = new MemoryStream()) {
        using (var ds = new DeflateStream(msIn, CompressionMode.Decompress)) {
            ds.CopyTo(msOut);
        }

        return Encoding.UTF8.GetString(msOut.ToArray());
    }
}

Si vous n'êtes pas sûr, non, je ne plaisante pas (mais peut-être que je mens). Ça va marcher. J'ai construit des tonnes de tests unitaires pour le tester, et j'ai même utilisé (une partie de) tests de conformité. C'est un tokenizer, pas un analyseur à part entière, donc il divisera seulement le XML dans ses jetons de composants. Il ne va pas analyser / intégrer les DTD.

Oh ... si vous voulez le code source de la regex, avec quelques méthodes auxiliaires:

regex pour tokenize un xml ou l'expression rationnelle complète 


452



En shell, vous pouvez analyser HTML en utilisant:

  • sed bien que:

    1. Turing.sed
    2. Ecrire un analyseur HTML (devoirs)
    3. ???
    4. Profit!
  • hxselect de html-xml-utils paquet

  • vim/ex (qui peut facilement sauter entre les balises html), par exemple:

    • suppression de la balise de style avec le code interne:

      $ curl -s http://example.com/ | ex -s +'/<style.*/norm nvatd' +%p -cq! /dev/stdin
      
  • grep, par exemple:

    • extraire le html externe de H1:

      $ curl -s http://example.com/ | grep -o '<h1>.*</h1>'
      <h1>Example Domain</h1>
      
    • extraire le corps:

      $ curl -s http://example.com/ | tr '\n' ' ' | grep -o '<body>.*</body>'
      <body> <div> <h1>Example Domain</h1> ...
      
  • html2text à l'analyse de texte en clair:

  • en utilisant xpath (XML::XPath module perl), voir exemple ici

  • perl ou Python (voir Exemple @Gilles)

  • pour analyser plusieurs fichiers à la fois, voir: Comment analyser cent fichiers de code source html dans shell?


Relatif (pourquoi ne pas utiliser regex match):


285