Question

Je suis à la recherche d'un moyen rapide pour analyser les balises HTML sur une chaîne de ColdFusion. Nous retirons dans un flux RSS, qui pourrait avoir quelque chose en elle. Nous faisons alors une certaine manipulation de l'information, puis crachant en arrière vers un autre endroit. À l'heure actuelle, nous faisons cela avec une expression régulière. Y at-il une meilleure façon de le faire?

<cfloop from="1" to="#ArrayLen(myFeed.item)#" index="i">
  <cfset myFeed.item[i].description.value = 
   REReplaceNoCase(myFeed.item[i].description.value, '<(.|\n)*?>', '', 'ALL')>
</cfloop>

Nous utilisons ColdFusion 8.

Était-ce utile?

La solution

Disclaimer Je suis un ardent défenseur de l'aide d'un analyseur syntaxique (au lieu de regex) pour analyser HTML. Cependant, cette question ne concerne pas l'analyse syntaxique HTML, mais de détruire il. Pour toutes les tâches qui vont au-delà, utiliser un analyseur.


Je pense que votre regex est bon. Tant qu'il n'y a rien de plus que enlever toutes les balises HTML à partir de l'entrée, en utilisant une expression régulière comme le vôtre est sûr.

Tout le reste serait probablement plus de tracas que cela vaut la peine, mais vous pouvez écrire une petite fonction qui effectue une boucle dans la chaîne char-par-char une fois et supprime tout ce qui est entre crochets d'étiquette - .: par exemple

  • interrupteur sur un drapeau « Intag » dès que vous rencontrez un caractère « < »,
  • éteindre dès que vous rencontrez « > »
  • caractères de copie à la chaîne de sortie aussi longtemps que le drapeau est éteint
  • pour la performance, utilisez un objet StringBuilder Java au lieu de concaténation de chaîne

Pour une partie forte demande de votre application, cela peut être plus rapide que l'expression rationnelle. Mais l'expression régulière est propre et sans doute assez vite.

Peut-être regex modifié a quelques avantages pour vous:

<[^>]*(?:>|$)
  • attrape les balises non fermées à la fin de la chaîne
  • [^>]* est mieux que (.|\n)

L'utilisation de REReplaceNoCase() est inutile quand il n'y a pas de lettres réelles dans le modèle. correspondant regex insensible à la casse est plus lent que de le faire sensible à la casse.

Autres conseils

HTML n'est pas une langue ordinaire, donc en utilisant des expressions régulières sur (non contrôlé) HTML est quelque chose qui devrait être fait avec grand soin (le cas échéant).

Prenons, par exemple, les éléments suivants valide segment HTML:

<img src="boat.jpg" alt="a boat" title="My boat is > everything! I <3 my boat!">

Vous remarquerez comment le surligneur de syntaxe est étouffait que -. Tout comme le regex existant qui a été offert

Sauf si vous pouvez être certains que la chaîne vous traitement ne sera pas contenir du code HTML similaire à ce qui précède, vous devriez éviter de faire des hypothèses / compromis, un seul / pur route regex vous forcer à faire.

(Note:. Le même problème se pose à la méthode char-par-char suggéré aussi)


Pour résoudre votre problème, vous devez utiliser un analyseur DOM pour analyser votre chaîne dans un objet HTML, une boucle à travers chaque élément et conversion en texte.

Si vous avez XHTML valide, vous pouvez alors utiliser le XmlParse() CF pour produire l'objet que vous pouvez ensuite en boucle bien. Si elle peut être HTML non-XML alors il n'y a aucune option intégrée avec CF8, de sorte que vous devrez étudier les options en Java / etc.

J'utilise ceci:

REReplaceNoCase(text, "<[^[:space:]][^>]*>", "", "ALL");

99% des cas, il fonctionne très bien.

La meilleure façon est généralement de contraindre < à &lt; et > à &gt;. De cette façon, vous n'êtes pas des suppositions sur la nature du message. Quelqu'un peut parler de <tags> ou d'essayer d'être <<expressive>> ou décrire une combinaison de touches ou à l'aide <Ctrl>+C 1 < x > 3 maths. Même smileys pourraient déclencher le <8P X> regex

<cfloop from="1" to="#ArrayLen(myFeed.item)#" index="i">
    <cfset myFeed.item[i].description.value = ReplaceList(myFeed.item[i].description.value, '<,>', '&lt;,&gt;')>
</cfloop>

cflib est votre ami: stripHTML

<cfset a = "<b><font color = 'red'>(PCB) <1 ppm </font></b>">

<cfset b = REReplaceNoCase(a, "<[^><]*>", '', 'ALL')>

<cfdump var="#b#">

sortie b = "(PCB) <1 ppm"

Le Regex « <[^> <] *> » supprimera tous les tags et les personnages à l'intérieur de ces balises et ne supprimera pas les balises simples comme qui peut être utilisé comme inférieur ou supérieur symbole dans la chaîne

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top