Problem "Escaping HMTL" with StringEscapeUtils

BigChicken

Mitglied
Morgen,

ich hab da ein Problem, das bestimmt schon häufiger aufgetaucht ist, aber ich konnte nichts dazu finden.

Ich habe einen String msg. In diesen möchte ich nun für die Anzeige im HTML alle Sonderzeichen codieren. Hierfür benuzer ich StringEscapeUtils.escapeHtml(msg).
Das funktioniert auch so weit... aber leider können in meinen String auch Teile vorkommen in denen die Sonderzeichen nicht escaped werden sollen (z.B. {1}, oder <em> oder </strong> <p class="...">, usw). Also zum Teil HMTL Tags zum Teil auch Platzhalter.

Jetzt will ich mir eine Funktion schreiben die z.B. eine String[] von regulären Ausdrücken übergeben bekommen und dann nur das mit escapeHtml() behandelt das nicht unter einen dieser regulären Ausdrücke fällt.

Leider ist mir bislang noch nichts effizientes eingefallen :confused:. Hat wer von Euch eine Idee?

Grüsse,
André
 
Morgen,

ich hab da ein Problem, das bestimmt schon häufiger aufgetaucht ist, aber ich konnte nichts dazu finden.

Ich habe einen String msg. In diesen möchte ich nun für die Anzeige im HTML alle Sonderzeichen codieren. Hierfür benuzer ich StringEscapeUtils.escapeHtml(msg).
Das funktioniert auch so weit... aber leider können in meinen String auch Teile vorkommen in denen die Sonderzeichen nicht escaped werden sollen (z.B. {1}, oder <em> oder </strong> <p class="...">, usw). Also zum Teil HMTL Tags zum Teil auch Platzhalter.

Jetzt will ich mir eine Funktion schreiben die z.B. eine String[] von regulären Ausdrücken übergeben bekommen und dann nur das mit escapeHtml() behandelt das nicht unter einen dieser regulären Ausdrücke fällt.

Leider ist mir bislang noch nichts effizientes eingefallen :confused:. Hat wer von Euch eine Idee?

Grüsse,
André

Ob meine Methode nun effizient ist oder nicht, sei mal dahingestellt. Auf alle Fälle sollte sie genau das tun, was du benötigst ;)
Habe die Funktion nicht auf Last getestet, du darfst mal Versuchskaninchen spielen ;)

Java:
import java.util.TreeMap;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringEscapeUtils;

public class ConvertHelper {
	public static void main(String[] args) {
		// Text definieren
		String unEscapedText =
			"Text mit HTML-Tags wie <b> oder <table> oder </b> oder </table>" +
			"etc. und Anführungszeichen \" \', .... {1}, oder <em> oder " +
			"</strong> <p class=\"...\">, Umlaute ä ö ü Ä Ö Ü"
		;

		// Ausnahmen definieren (erstes Beispiel lässt alle <b>, </b>, <strong> und </strong> zu
		String[] excludeList = {"<(/?b|/?strong)>", "<p class=\"...\">", "Ä"};

		// Text escapen lassen ohne die Ausnahmen
		String escapedText = escapeHtml(unEscapedText, excludeList);

		// escapten Text ausgeben lassen
		System.out.println(escapedText);
	}

	private static String escapeHtml(String text, String[] exclusionList) {
		TreeMap<Integer, String> excludeTempMap = new TreeMap<Integer, String>();

		// Ersetzt alle Ausnahmen mit einem eindeutigen String.
		// In diesem Falle mit dem hashCode des Strings, was
		// wegen der Eindeutigkeit im Text selbst vielleicht zu
		// Problemen führen könnte ;)
		for(String excludePart : exclusionList) {
			Matcher matcher = Pattern.compile(excludePart, Pattern.MULTILINE).matcher(text);

			while(matcher.find()) {
				String match = matcher.group();
				Integer matchHash = match.hashCode();

				// Ersetze Pattern 
				text = matcher.replaceFirst(String.valueOf(matchHash));

				// Merke jeweiliges Paar "hashCode zu Ausnahme"
				excludeTempMap.put(matchHash, match);

				// Setze aktuellen Text zum nächsten Matching 
				matcher.reset(text);
			}
		}

		// Ersetzung der restlichen HTML-Zeichen
		text = StringEscapeUtils.escapeHtml(text);

		// Umgekehrte Ersetzung der Ausnahmen von hashCode zur Ausnahme selbst
		for(Entry<Integer, String> excludeEntry : excludeTempMap.entrySet()) {
			text = text.replaceAll(
				String.valueOf(excludeEntry.getKey()),
				excludeEntry.getValue()
			);
		}

		return text;
	}
}

Habe den Code so halbwegs kommentiert. Wenn es noch Fragen gibt, nur zu ;)

Viele Grüße,
MAN
 
Zuletzt bearbeitet:
Hi,

vielen Dank. Hab es gerade auch direkt ausgetestet und funktioniert genau wie ich es wollte. Musste mir nur die Funktion auf ne alte Java-Version anpassen, weil in dem Projekt hier noch 1.4 benutzt wird.
Jetzt kann ich mir noch nen paar gescheite regEx ausdenken und dann sollte ich alle Ausnahmen abfangen können.

Nochmals vielen Dank!

Grüsse,
André
 
Zuletzt bearbeitet:
Zurück