Domanda

Sto cercando un modo rapido per analizzare i tag HTML di ColdFusion stringa.Stiamo tirando in un feed RSS, che potrebbe potenzialmente avere nulla in esso.Ci sono poi fare qualche manipolazione delle informazioni e poi sputare di nuovo in un altro luogo.Attualmente stiamo facendo questo con una espressione regolare.C'è un modo migliore per fare questo?

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

Stiamo usando ColdFusion 8.

È stato utile?

Soluzione

responsabilità Sono un fiero sostenitore di usare una vera e propria parser (invece di regex) per analizzare HTML. Tuttavia, la questione non si tratta di l'analisi HTML, ma di distruggendo di esso. Per tutte le attività che vanno oltre questo, utilizzare un parser.


Credo che la vostra regex è buono. Fino a quando non v'è nulla di più di rimozione di tutti i tag HTML da l'ingresso, utilizzando un'espressione regolare come la tua è sicuro.

Tutto il resto sarebbe probabilmente più problemi di quanto ne vale la pena, ma si potrebbe scrivere una piccola funzione che scorre la stringa char-by-char volta e rimuove tutto ciò che è tra parentesi tag - ad es .:

  • interruttore su una bandiera "Intag" non appena si incontra un carattere "<",
  • spegnerlo non appena si incontrano ">"
  • caratteri di copia alla stringa di uscita fino a quando la bandiera è spento
  • per le prestazioni, utilizzare un oggetto StringBuilder Java invece di concatenazione di stringhe

Per una parte alta richiesta della vostra applicazione, questo può essere più veloce rispetto alla regex. Ma l'espressione regolare è pulita e probabilmente abbastanza veloce.

Forse questo regex modificato ha alcuni vantaggi per voi:

<[^>]*(?:>|$)
  • cattura i tag non chiusi alla fine della stringa
  • [^>]* è migliore di (.|\n)

L'uso di REReplaceNoCase() non è necessaria quando non ci sono le lettere reali nel modello. Case-insensitive corrispondenza regex è più lento di farlo caso-sensibile.

Altri suggerimenti

HTML non è un Normale linguaggio, in modo da utilizzare le espressioni Regolari su (incontrollata) HTML è qualcosa che dovrebbe essere fatto con grande cura (se a tutti).

Si consideri, ad esempio, il seguente valido segmento di codice HTML:

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

Si noti come l'evidenziatore di sintassi è soffocamento su che - come sarà l'esistente regex che è stato offerto.

A meno che non si può essere certo che la stringa che si sta elaborando non contengono codice HTML simile al precedente, si dovrebbe evitare di fare ipotesi/compromesso, che una singola/puro regex percorso avrebbe la forza di fare.

(Nota:Lo stesso problema vale per il suggerito carattere metodo di troppo.)


Per risolvere il tuo problema, è necessario utilizzare un parser DOM per analizzare la vostra stringa in un oggetto HTML, loop attraverso ogni elemento e conversione in testo.

Se si dispone di XHTML valido, allora è possibile utilizzare CF XmlParse() per produrre l'oggetto, che è quindi possibile loop però.Se si potrebbe essere non-XML, HTML, allora non c'è built-in opzione con CF8, quindi dovrete esaminare le opzioni in Java/etc.

Io uso questo:

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

99% dei casi funziona bene.

Il modo migliore è di solito per costringere < a &lt; e > a &gt;. In questo modo non stanno facendo ipotesi circa la natura del messaggio. Qualcuno potrebbe parlare di <tags> o cercando di essere <<expressive>> o descrivere un <Ctrl>+C tasto o usando la matematica 1 < x > 3. Anche faccine potrebbe innescare la <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 è tuo amico: stripHTML

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

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

<cfdump var="#b#">

uscita b = "(PCB) <1 ppm"

Il Regex "<[^> <] *>" rimuoverà tutti i tag e i personaggi all'interno di questi tag e non rimuoverà i tag singoli come , che può essere usato come minore o maggiore di simbolo nella stringa

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top