2010-11-25 6 views
0

J'ai un script coldfusion que j'ai eu pendant un moment sur mon système de gestion de contenu. Il utilise regex pour éliminer les balises et les caractères foireux du contenu.Regex Balayage des balises HTML

Je dois arrêter ce script pour enlever les balises <object> et .

Je suis en train d'essayer, mais je pense que c'est au-delà de mes compétences en regex.

http://pastebin.com/rTtMyiQw

<cfparam name="Attributes.allowedclasses" default=""> 

<!--- turn allowed classes list to regular expression ---> 
<cfset Attributes.allowedclasses = Replace(Attributes.allowedclasses, ",", "|", "all")> 

<cfset vBody="<body style='font-family:Verdana; font-size:12px;'>"> 
<cfset vStart="<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html xmlns='http://www.w3.org/1999/xhtml' lang='en' xml:lang='en'><head><title>Title</title></head>#vBody#"> 
<cfset vEnd="</body></html>"> 

<cfloop list="#Attributes.varnames#" index="theVariable"> 

    <cfset vIntVar=evaluate("caller.#theVariable#")> 

    <cf_bocctrimformvars varnames="vIntVar" allowhtml="yes" quotes="unescape" allowPound="yes"> 

    <cfset vIntVarDebug=vIntVar> 

    <!--- strip copy and paste word etc code formatting ---> 

    <cfset vIntVar=ReReplaceNoCase(vIntVar, "</?[a-z0-9-=""'!\$\?%&\*\[email protected]~##;,\\]*:[a-z0-9 -=""'!\$\?%&\*\[email protected]~##;,\\]*>", "", "all")> 

    <!--- stop certain classes being stripped out ---> 
    <cfif ListLen(Attributes.allowedclasses) NEQ 0> 
     <cfset vIntVar=ReReplaceNoCase(vIntVar, '<span class="(#Attributes.allowedclasses#)">([\s\S]*?)</span>', '<excludespan classexclude="\1">\2</excludespan>', 'all')> 

     <!--- stop other classes being stripped out ---> 
     <cfset vIntVar=ReReplaceNoCase(vIntVar, '<([a-z0-9]+) class="(#Attributes.allowedclasses#)"[^>]*>', '<\1 classexclude="\2">', 'all')> 
    </cfif> 

    <!--- strip out span and font tags ---> 
    <cfset vIntVar=ReReplaceNoCase(vIntVar, "</?(span|font)[^>]*>", "", "all")> 

    <!--- strip out rest of styles/classes ---> 
    <cfset vIntVar=ReReplaceNoCase(vIntVar, "<([a-z0-9]+) (style|class)=[^>]*>", "<\1>", "all")> 

    <!--- reset classes which shouldn't be stripped out ---> 
    <cfif ListLen(Attributes.allowedclasses) NEQ 0> 
     <cfset vIntVar=ReReplaceNoCase(vIntVar, '<excludespan classexclude="([a-z0-9-]+)"[^>]*>', '<span class="\1">', 'all')> 
     <cfset vIntVar=ReplaceNoCase(vIntVar, '</excludespan>', '</span>', 'all')> 

     <cfset vIntVar=ReReplaceNoCase(vIntVar, '<([a-z0-9]+) classexclude="([a-z0-9-]+)"[^>]*>', '<\1 class="\2">', 'all')> 
    </cfif> 



    <cfset vIntVar=ReReplaceNoCase(vIntVar, "<\?xml[^>]*>", "", "all")> 
    <cfset vIntVar=ReReplaceNoCase(vIntVar, "<p>([[:space:]])*</p>", "", "all")> 
    <cfset vIntVar=ReReplaceNoCase(vIntVar, "</?U>", "", "all")> 
    <cfset vIntVar=ReReplaceNoCase(vIntVar, "</?DIV[^>]*>", "", "all")> 
    <cfset vIntVar=ReReplaceNoCase(vIntVar, "</?PRE>", "", "all")> 
    <cfset vIntVar=ReplaceNoCase(vIntVar, 'target=""', '', 'all')> 

    <!--- 
    DG 19/9/2004: fix put in to swap round <p> and <a> tags if a single <p> is inside an <a> 
    (which html tidy doesn't like 
    ---> 
    <cfset vIntVar=ReReplaceNoCase(vIntVar, "<a([[:print:]]*)>[[:space:]]*<p>([[:print:]]*)</p>([[:space:]]*)</a>", "<p><a\1>\2</a></p>", 'all')> 

    <cfset vIntVar=vStart & vIntVar & vEnd> 

    <cflock name="tidy" type="exclusive" timeout="10"> 
     <cfscript> 
     TidyObj = CreateObject("COM", "TidyCOM.TidyObject"); 
     TidyOptions = TidyObj.Options; 
     TidyOptions.Doctype = "omit"; 
     TidyOptions.TidyMark = false; 
     TidyOptions.OutputXml = false; 
     TidyOptions.InputXml = false; 
     TidyOptions.OutputXhtml = true; 
     TidyOptions.ShowWarnings = false; 
     TidyOptions.DropEmptyParas = true; 
     TidyOptions.Quiet = true; 
     TidyOptions.Indent = 0; 
     TidyOptions.Wrap = 0; 
     TidyOptions.QuoteAmpersand = true; 

     vIntVar = TidyObj.TidyMemToMem(vIntVar); 

     TidyObj = ""; 
     </cfscript> 
    </cflock> 


    <!--- strip any image tags inserted by drag and drop etc ---> 
    <cfset vIntVar=ReReplaceNoCase(vIntVar, "<img [^>]*>", "", "all")> 


</cfloop> 
+1

Je devrais vous avertir, en demandant des questions de parsing-html-with-regex a tendance à être un peu mal vu sur rond ici - voir ceci: http://stackoverflow.com/questions/1732348/regex-match-open-tags- sauf-xhtml-self-contained-tags/1732454 # 1732454 –

+0

Je peux comprendre que ce n'est pas populaire. C'est un vieux script. Plutôt que de tout réécrire, j'ai juste besoin d'une solution rapide pour le moment. – Sam

+2

Sérieusement? Vous devez au moins faire le travail d'identifier où dans le code que vous avez fourni les étiquettes en question. Alors quelqu'un pourrait être enclin à répondre à votre question. – orangepips

Répondre

1

Je suis d'accord avec orangepips, vous devriez poser une question plus précise mais je aussi comme un défi. J'ai essayé d'analyser HTML avec REGEX avant et je peux témoigner que ce n'est pas une bonne solution, surtout quand vous regardez un document entier et pas seulement une simple chaîne. Cependant, parfois vous devez travailler avec un espace restreint et vous n'avez pas beaucoup d'options.

J'ai parcouru toutes les expressions REGEX que vous avez ici et les ai toutes lancées par rapport à l'étiquette d'objet suivante. Aucun d'entre eux n'a détecté l'étiquette d'objet, ce qui me porte à croire que le problème pourrait être dans TidyCOM. Je me suis renseigné un peu sur TidyCOM et les choses les plus récentes que j'ai pu trouver datent de 2001.

Je comprends que vous cherchez simplement à corriger ce script et à passer à autre chose, mais ce n'est peut-être pas possible. Vous pourriez commencer à penser à migrer ce contenu hérité vers une plateforme plus récente.

Si vous voulez savoir avec certitude où le problème est généré, entrez la variable vIntVar dans un fichier texte après la concaténation de vStart, vIntVar et vEnd. Bien sûr, vous pouvez également utiliser le débogueur CF, mais je me souviens que ce n'était pas la chose la plus facile à faire.

balise Object j'ai utilisé pour tester les expressions:

<object classid="clsid:F08DF954-8592-11D1-B16A-00C0F0283628" id="Slider1" width="100" height="50"> 
    <param name="BorderStyle" value="1" /> 
    <param name="MousePointer" value="0" /> 
    <param name="Enabled" value="1" /> 
    <param name="Min" value="0" /> 
    <param name="Max" value="10" /> 
</object> 

Si vous avez besoin d'aide pour comprendre ce que les expressions RegEx font que j'ai trouvé Expresso être un excellent outil. Il y en a d'autres mais c'est celui que j'ai utilisé pendant des années et ça fait le boulot.

+0

On dirait que j'ai collé le code complet au lieu de ma version dépouillée. J'ai passé la majeure partie du vendredi à travailler dessus et j'ai tout réussi. J'ai enlevé le TidyCOM et fait le travail avec une regex personnalisée qui fait le travail bien. Je suis sûr que pour une manipulation plus complexe, il existe d'autres méthodes qui sont plus appropriées, mais comme vous l'avez dit parfois, vous devez travailler dans des espaces restreints. Je pense que vous avez mis le doigt sur la tête avec celui-ci Ryan, merci pour votre aide. – Sam

Questions connexes