J'essaie de faire correspondre les <input>
champs de type «masqués» en utilisant ce modèle:
/<input type="hidden" name="([^"]*?)" value="([^"]*?)" />/
Voici un exemple de données de formulaire:
<input type="hidden" name="SaveRequired" value="False" /><input type="hidden" name="__VIEWSTATE1" value="1H4sIAAtzrkX7QfL5VEGj6nGi+nP" /><input type="hidden" name="__VIEWSTATE2" value="0351118MK" /><input type="hidden" name="__VIEWSTATE3" value="ZVVV91yjY" /><input type="hidden" name="__VIEWSTATE0" value="3" /><input type="hidden" name="__VIEWSTATE" value="" /><input type="hidden" name="__VIEWSTATE" value="" />
Mais je ne suis pas sûr que type
, name
, et value
attributs apparaîtront toujours dans le même ordre. Si l' type
attribut vient en dernier, la correspondance échouera car dans mon modèle, c'est au début.
Question:
Comment puis-je modifier mon modèle pour qu'il corresponde quelle que soit la position des attributs dans la <input>
balise?
PS: Au fait, j'utilise l' outil de bureau RegEx basé sur Adobe Air pour tester les expressions régulières.
Réponses:
Contrairement à toutes les réponses ici, car ce que vous essayez de faire regex est une solution parfaitement valable. C'est parce que vous n'essayez PAS de faire correspondre des balises équilibrées - CELA serait impossible avec regex! Mais vous ne faites correspondre que ce qui se trouve dans une balise, et c'est parfaitement normal.
Voici le problème, cependant. Vous ne pouvez pas le faire avec une seule regex ... vous devez faire une correspondance pour capturer une
<input>
balise, puis effectuer un traitement supplémentaire à ce sujet. Notez que cela ne fonctionnera que si aucune des valeurs d'attribut ne contient de>
caractère, donc ce n'est pas parfait, mais cela devrait suffire pour des entrées saines.Voici un (pseudo) code Perl pour vous montrer ce que je veux dire:
Le principe de base ici est de ne pas essayer d'en faire trop avec une seule expression régulière. Comme vous l'avez remarqué, les expressions régulières imposent un certain ordre. Donc, ce que vous devez faire à la place est d'abord de faire correspondre le CONTEXTE de ce que vous essayez d'extraire, puis de faire un sous-appariement sur les données que vous voulez.
EDIT: Cependant, je conviendrai qu'en général, utiliser un analyseur HTML est probablement plus facile et meilleur et vous devriez vraiment envisager de reconcevoir votre code ou de réexaminer vos objectifs. :-) Mais j'ai dû poster cette réponse pour contrer la réaction instinctive selon laquelle l'analyse de tout sous-ensemble de HTML est impossible: HTML et XML sont tous les deux irréguliers lorsque l'on considère l'ensemble de la spécification, mais la spécification d'une balise est décemment régulière , certainement à la portée de PCRE.
la source
Oh oui, vous pouvez utiliser des expressions régulières pour analyser le HTML!
Pour la tâche que vous tentez, les expressions régulières sont parfaitement bien!
Il est vrai que la plupart des gens sous-estiment la difficulté d'analyser le HTML avec des expressions régulières et le font donc mal.
Mais ce n'est pas un défaut fondamental lié à la théorie computationnelle. Cette sottise est souvent évoquée ici , mais ne les croyez pas.
Donc, même si cela peut certainement être fait (cette publication sert de preuve d'existence de ce fait incontestable), cela ne signifie pas que cela devrait l' être.
Vous devez décider par vous-même si vous êtes à la hauteur de la tâche d'écrire ce qui équivaut à un analyseur HTML dédié et spécial à partir des expressions rationnelles. La plupart des gens ne le sont pas.
Mais je le suis. ☻
Solutions d'analyse HTML générales basées sur les expressions régulières
Je vais d'abord montrer à quel point il est facile d'analyser du HTML arbitraire avec des expressions rationnelles. Le programme complet est à la fin de cette publication, mais le cœur de l'analyseur est:
Vous voyez à quel point c'est facile à lire?
Tel qu'il est écrit, il identifie chaque morceau de HTML et indique où il l'a trouvé. Vous pouvez facilement le modifier pour faire tout ce que vous voulez avec n'importe quel type de pièce donné, ou pour des types plus particuliers que ceux-ci.
Je n'ai aucun cas de test défaillant (à gauche :): j'ai exécuté avec succès ce code sur plus de 100 000 fichiers HTML - chacun d'entre eux que je pourrais rapidement et facilement mettre la main sur. Au-delà de ceux-ci, je l'ai également exécuté sur des fichiers spécialement conçus pour briser les analyseurs naïfs.
Ce n'est pas un analyseur naïf.
Oh, je suis sûr que ce n'est pas parfait, mais je n'ai pas encore réussi à le casser. Je pense que même si quelque chose se produisait, le correctif serait facile à intégrer en raison de la structure claire du programme. Même les programmes contenant beaucoup de regex devraient avoir une structure.
Maintenant que ce n'est plus le cas, permettez-moi de répondre à la question du PO.
Démo de la résolution de la tâche du PO à l'aide des expressions rationnelles
Le petit
html_input_rx
programme que j'inclus ci-dessous produit la sortie suivante, afin que vous puissiez voir que l'analyse HTML avec des expressions régulières fonctionne parfaitement pour ce que vous souhaitez faire:Analyser les balises d'entrée, voir aucune entrée mauvaise
Voici la source du programme qui a produit la sortie ci-dessus.
Voilà! Rien pour le faire! :)
Vous seul pouvez juger si votre compétence avec les regex est à la hauteur d'une tâche d'analyse particulière. Le niveau de compétence de chacun est différent et chaque nouvelle tâche est différente. Pour les travaux où vous avez un ensemble d'entrées bien défini, les expressions régulières sont évidemment le bon choix, car il est trivial d'en rassembler lorsque vous avez un sous-ensemble restreint de HTML à gérer. Même les débutants en regex devraient gérer ces tâches avec des regex. Tout le reste est exagéré.
Cependant , une fois que le HTML commence à devenir moins cloué, une fois qu'il commence à se ramifier d'une manière que vous ne pouvez pas prédire mais qui est parfaitement légale, une fois que vous devez faire correspondre des sortes de choses plus différentes ou avec des dépendances plus complexes, vous finirez par atteindre un point où vous devez travailler plus dur pour effectuer une solution qui utilise des expressions régulières que vous auriez à utiliser une classe d'analyse. L'endroit où ce seuil de rentabilité tombe dépend encore une fois de votre propre niveau de confort avec les expressions régulières.
Donc qu'est ce que je devrais faire?
Je ne vais pas vous dire ce que vous devez faire ou ce que vous ne pouvez pas faire. Je pense que c'est faux. Je veux juste vous présenter des possibilités, ouvrez un peu les yeux. Vous pouvez choisir ce que vous voulez faire et comment vous voulez le faire. Il n'y a pas d'absolus - et personne d'autre ne connaît votre propre situation aussi bien que vous-même. Si quelque chose semble être trop de travail, eh bien, c'est peut-être le cas. La programmation doit être amusante , vous savez. Si ce n'est pas le cas, vous le faites peut-être mal.
On peut regarder mon
html_input_rx
programme de plusieurs manières valables. L'une d'elles est que vous pouvez en effet analyser le HTML avec des expressions régulières. Mais une autre est que c'est beaucoup, beaucoup, beaucoup plus difficile que presque tout le monde ne le pense. Cela peut facilement conduire à la conclusion que mon programme témoigne de ce que vous ne devriez pas faire, car c'est vraiment trop difficile.Je ne suis pas en désaccord avec cela. Certes, si tout ce que je fais dans mon programme n'a pas de sens pour vous après quelques études, alors vous ne devriez pas essayer d'utiliser des regex pour ce genre de tâche. Pour du HTML spécifique, les expressions régulières sont excellentes, mais pour du HTML générique, elles équivalent à de la folie. J'utilise des classes d'analyse tout le temps, surtout si c'est du HTML que je n'ai pas généré moi-même.
Les expressions régulières optimales pour les petits problèmes d'analyse HTML, pessimales pour les gros problèmes
Même si mon programme est considéré comme une illustration de la raison pour laquelle vous ne devriez pas utiliser les expressions régulières pour analyser le HTML général - ce qui est OK, parce que je voulais en quelque sorte que ce soit cela ☺ - cela devrait quand même être une révélation afin que plus de gens cassent le terriblement commun et la mauvaise habitude d'écrire des motifs illisibles, non structurés et non maintenables.
Les motifs ne doivent pas être laids et ils ne doivent pas nécessairement être durs. Si vous créez des motifs laids, c'est une réflexion sur vous, pas sur eux.
Langage Regex phénoménalement exquis
On m'a demandé de signaler que ma solution proposée à votre problème a été écrite en Perl. Êtes-vous surpris? N'avez-vous pas remarqué? Cette révélation est-elle une bombe?
Il est vrai que tous les autres outils et langages de programmation ne sont pas aussi pratiques, expressifs et puissants en matière d'expressions rationnelles que Perl. Il existe un large spectre, certains étant plus adaptés que d'autres. En général, les langages qui ont exprimé des expressions rationnelles comme faisant partie du langage de base plutôt que comme une bibliothèque sont plus faciles à utiliser. Je n'ai rien fait avec les expressions régulières que vous ne pourriez pas faire dans, par exemple, PCRE, même si vous structureriez le programme différemment si vous utilisiez C.
Finalement, d'autres langages seront rattrapés par la situation actuelle de Perl en termes de regex. Je dis cela parce qu'à l'époque où Perl a commencé, personne d'autre n'avait rien de tel que les expressions régulières de Perl. Dites ce que vous voulez, mais c'est là que Perl a clairement gagné: tout le monde a copié les expressions rationnelles de Perl, bien qu'à des stades variables de leur développement. Perl a été le pionnier de presque (pas tout à fait, mais presque) tout ce sur quoi vous vous êtes habitué dans les modèles modernes, quel que soit l'outil ou le langage que vous utilisez. Donc , finalement les autres vont rattraper leur retard.
Mais ils ne rattraperont que la position de Perl dans le passé, comme c'est le cas maintenant. Tout avance. Dans les expressions régulières, si rien d'autre, là où Perl mène, d'autres suivent. Où sera Perl une fois que tout le monde aura enfin compris où Perl est maintenant? Je n'en ai aucune idée, mais je sais que nous aussi nous aurons déménagé. Nous serons probablement plus proches du style de création de motifs de Perl₆ .
Si vous aimez ce genre de chose mais que vous souhaitez l'utiliser en Perl₅, vous pourriez être intéressé par le merveilleux module Regexp :: Grammars de Damian Conway . C'est complètement génial, et ce que j'ai fait ici dans mon programme semble tout aussi primitif que le mien, ce qui fait que les gens s'entassent sans espaces ni identificateurs alphabétiques. Vérifiez-le!
Chunker HTML simple
Voici la source complète de l'analyseur dont j'ai montré la pièce maîtresse au début de cette publication.
Je ne suggère pas que vous devriez utiliser ceci sur une classe d'analyse rigoureusement testée. Mais je suis fatigué des gens qui prétendent que personne ne peut analyser du HTML avec des expressions régulières simplement parce qu'ils ne le peuvent pas. Vous pouvez clairement, et ce programme est la preuve de cette affirmation.
Bien sûr, il est pas facile, mais il est possible!
Et essayer de le faire est une terrible perte de temps, car il existe de bonnes classes d'analyse que vous devriez utiliser pour cette tâche. La bonne réponse aux personnes qui essaient d'analyser du HTML arbitraire n'est pas que ce soit impossible. C'est une réponse facile et malhonnête. La réponse correcte et honnête est qu'ils ne devraient pas essayer parce que c'est trop ennuyeux de partir de zéro; ils ne doivent pas se casser le dos en cherchant à réinventer une roue qui fonctionne parfaitement.
D'un autre côté, le HTML qui appartient à un sous - ensemble prévisible est ultra-facile à analyser avec les expressions rationnelles. Il n'est pas étonnant que les gens essaient de les utiliser, car pour de petits problèmes, des problèmes de jouets peut-être, rien de plus facile. C'est pourquoi il est si important de distinguer les deux tâches - spécifiques et génériques - car elles ne nécessitent pas nécessairement la même approche.
J'espère à l'avenir voir ici un traitement plus juste et plus honnête des questions sur le HTML et les expressions régulières.
Voici mon lexer HTML. Il n'essaye pas de faire une analyse de validation; il identifie simplement les éléments lexicaux. Vous pourriez le considérer plus comme un bloc HTML que comme un analyseur HTML. Il ne pardonne pas très bien le HTML cassé, bien que cela fasse de très petites allocations dans cette direction.
Même si vous n'analysez jamais le code HTML complet vous-même (et pourquoi devriez-vous? C'est un problème résolu!), Ce programme a beaucoup de bits regex sympas dont je pense que beaucoup de gens peuvent apprendre beaucoup. Prendre plaisir!
la source
//input[@type="hidden"]
. Ou si vous ne voulez pas utiliser xpath, récupérez simplement toutes les entrées et filtrez celles qui sont masquéesgetAttribute
.Je préfère le n ° 2.
Résultat:
la source
Dans l'esprit de la solution lexer de Tom Christiansen, voici un lien vers l'article de 1998 apparemment oublié de Robert Cameron, REX: XML Shallow Parsing with Regular Expressions.
http://www.cs.sfu.ca/~cameron/REX.html
Si vous aimez lire sur les expressions régulières, l'article de Cameron est fascinant. Son écriture est concise, approfondie et très détaillée. Il ne vous montre pas simplement comment construire l'expression régulière REX, mais aussi une approche pour construire une expression régulière complexe à partir de parties plus petites.
J'utilise l'expression régulière REX depuis 10 ans pour résoudre le type de problème sur lequel l'affiche initiale a posé la question (comment faire correspondre cette balise particulière mais pas une autre balise très similaire?). J'ai trouvé la regex qu'il a développée pour être complètement fiable.
REX est particulièrement utile lorsque vous vous concentrez sur les détails lexicaux d'un document - par exemple, lors de la transformation d'un type de document texte (par exemple, texte brut, XML, SGML, HTML) en un autre, où le document peut ne pas être valide, bien formé, voire analysable pour la majeure partie de la transformation. Il vous permet de cibler des îlots de balisage n'importe où dans un document sans déranger le reste du document.
la source
Bien que j'aime le contenu du reste de ces réponses, elles n'ont pas vraiment répondu à la question directement ou aussi correctement. Même la réponse de Platinum était trop compliquée et aussi moins efficace. J'ai donc été obligé de mettre ça.
Je suis un grand partisan de Regex, lorsqu'il est utilisé correctement. Mais à cause de la stigmatisation (et des performances), je déclare toujours qu'un XML ou HTML bien formé devrait utiliser un analyseur XML. Et des performances encore meilleures seraient l'analyse des chaînes, bien qu'il y ait une ligne entre la lisibilité si cela devient trop incontrôlable. Cependant, ce n'est pas la question. La question est de savoir comment faire correspondre une balise d'entrée de type masqué. La réponse est:
En fonction de votre saveur, la seule option regex que vous devez inclure est l'option ignorecase.
la source
<input type='hidden' name='Oh, <really>?' value='Try a real HTML parser instead.'>
>
dans le champ de nom sont presque nulles, il est en effet possible qu'il y ait un>
dans une poignée d'action. EG: Un appel javascript en ligne sur la propriété OnClick. Cela étant dit, j'ai un analyseur XML pour ceux-ci, mais aussi un Regex pour ceux où le document que je suis donné est trop foiré pour que les analyseurs XML puissent le gérer, mais un Regex le peut. De plus, ce n'était pas la question. Vous ne rencontrerez jamais ces situations avec une entrée cachée, et ma réponse est la meilleure.Ya, <really>!
./>
est un XML-ism; il n'est requis dans aucune version de HTML, sauf pour XHTML (qui n'a jamais vraiment gagné en popularité, et a été pratiquement remplacé par HTML5). Et vous avez raison de dire qu'il y a beaucoup de HTML malpropre et pas vraiment valide, mais un bon analyseur HTML (et non XML) devrait être capable d'en gérer la plupart; si ce n'est pas le cas, les navigateurs non plus.vous pouvez essayer ceci:
et pour un résultat plus proche, vous pouvez essayer ceci:
vous pouvez tester votre modèle regex ici http://regexpal.com/
ces pattens sont bons pour cela:
et pour un ordre aléatoire de
type
,name
etvalue
vous pouvez utiliser ceci:ou
sur ce :
»
au fait, je pense que vous voulez quelque chose comme ça:
ce n'est pas bon mais ça marche en aucune façon.
testez-le sur: http://regexpal.com/
la source
Je voudrais utiliser
**DOMDocument**
pour extraire le code html.BTW, vous pouvez le tester ici - regex101.com. Il montre le résultat en temps réel. Quelques règles sur Regexp: http://www.eclipse.org/tptp/home/downloads/installguide/gla_42/ref/rregexp.html Reader .
la source
supposons que votre contenu html soit stocké dans la chaîne html, puis pour obtenir chaque entrée qui contient le type masqué, vous pouvez utiliser une expression régulière
la recherche régulière ci-dessus
<input
suivie d'un nombre quelconque de caractères jusqu'à ce qu'elle obtiennetype="hidden"
ou tapez = 'hidden' suivi d'un nombre quelconque de caractères jusqu'à ce qu'elle obtienne>
/ g indique à l'expression régulière de trouver chaque sous-chaîne qui correspond au modèle donné.
la source