Grundsätzlich möchte ich ein bestimmtes HTML-Dokument dekodieren und alle Sonderzeichen ersetzen, z " "
→ " "
Und ">"
→ ">"
.
In .NETZwir können das nutzen HttpUtility.HtmlDecode Methode.
Was ist die entsprechende Funktion in Java?
yinyueyouge
Grundsätzlich möchte ich ein bestimmtes HTML-Dokument dekodieren und alle Sonderzeichen ersetzen, z " "
→ " "
Und ">"
→ ">"
.
In .NETZwir können das nutzen HttpUtility.HtmlDecode Methode.
Was ist die entsprechende Funktion in Java?
Kevin Hakanson
Ich habe Apache Commons verwendet StringEscapeUtils.unescapeHtml4() dafür:
Demaskiert eine Zeichenfolge, die Entitäts-Escapezeichen enthält, in eine Zeichenfolge, die die tatsächlichen Unicode-Zeichen enthält, die den Escapezeichen entsprechen. Unterstützt HTML 4.0-Entitäten.
Leider ist mir erst heute aufgefallen, dass es HTML-Sonderzeichen nicht sehr gut dekodiert 🙁
– Sid
13. Okt. 2010 um 20:04
Ein schmutziger Trick besteht darin, den Wert zunächst in einem ausgeblendeten Feld zu speichern, um ihn zu maskieren. Anschließend sollte das Zielfeld den Wert aus dem ausgeblendeten Feld erhalten.
– setzamora
16. Juni 2011 um 5:19
Die Klasse StringEscapeUtils ist veraltet und wurde verschoben Apache Commons-Text
– Pauli
3. Dezember 2018 um 22:16 Uhr
Ich möchte die Zeichenfolge konvertieren <p>üè</p>
Zu <p>üé</p>
mit StringEscapeUtils.unescapeHtml4()
Ich bekomme <p>üè</p>
. Gibt es eine Möglichkeit, vorhandene HTML-Tags intakt zu halten?
– Nickkk
13. Januar 2020 um 12:10 Uhr
Wenn ich so etwas habe “
Kann die Escape-Codierung geändert werden, die in Windows-1252 durch ein Anführungszeichen, in Unicode jedoch durch ein Steuerzeichen ersetzt wird?
– ifly6
11. Dezember 2020 um 13:21 Uhr
Tal
Die in anderen Antworten erwähnten Bibliotheken wären gute Lösungen, aber wenn Sie in Ihrem Projekt bereits reale HTML-Inhalte durchsuchen, ist die Jsoup
Projekt hat viel mehr zu bieten als nur das Verwalten „kaufmännisches Und-Zeichen, Pfund, FFFF, Semikolon“ Dinge.
// textValue: <p>This is a sample. \"Granny\" Smith –.<\/p>\r\n
// becomes this: This is a sample. "Granny" Smith –.
// with one line of code:
// Jsoup.parse(textValue).getText(); // for older versions of Jsoup
Jsoup.parse(textValue).text();
// Another possibility may be the static unescapeEntities method:
boolean strictMode = true;
String unescapedString = org.jsoup.parser.Parser.unescapeEntities(textValue, strictMode);
Außerdem erhalten Sie die praktische API zum Extrahieren und Bearbeiten von Daten unter Verwendung der besten DOM-, CSS- und CSS-Funktionen jQuery-ähnliche Methoden. Es ist Open Source und MIT-Lizenz.
upvote+, aber ich sollte darauf hinweisen, dass neuere Versionen von Jsoup verwendet werden .text()
anstatt .getText()
– SourceVisor
10. November 2016 um 16:25 Uhr
Vielleicht ist die Verwendung direkter org.jsoup.parser.Parser.unescapeEntities(String string, boolean inAttribute)
. API-Dokumente: jsoup.org/apidocs/org/jsoup/parser/…
– Danneu
1. Dezember 2016 um 21:17 Uhr
Das war perfekt, da ich Jsoup bereits in meinem Projekt verwende. Außerdem hatte @danneu recht – Parser.unescapeEntities funktioniert genau wie angekündigt.
– MandisaW
29. August 2017 um 17:23
Nick Frolov
Ich habe es versucht Apache Commons‘ StringEscapeUtils.unescapeHtml3() in meinem Projekt, aber ich war mit der Leistung nicht zufrieden. Es stellt sich heraus, dass viele unnötige Vorgänge ausgeführt werden. Zum einen wird für jeden Aufruf ein StringWriter zugewiesen, auch wenn es in der Zeichenfolge nichts zu entkommen gibt. Ich habe diesen Code anders umgeschrieben und jetzt funktioniert er viel schneller.
Der folgende Code entführt alle HTML 3 Symbole und numerische Escapezeichen (entspricht Apache unescapeHtml3). Sie können der Karte bei Bedarf einfach weitere Einträge hinzufügen HTML 4.
package com.example;
import java.io.StringWriter;
import java.util.HashMap;
public class StringUtils {
public static final String unescapeHtml3(final String input) {
StringWriter writer = null;
int len = input.length();
int i = 1;
int st = 0;
while (true) {
// Look for '&'
while (i < len && input.charAt(i-1) != '&')
i++;
if (i >= len)
break;
// Found '&', look for ';'
int j = i;
while (j < len && j < i + MAX_ESCAPE + 1 && input.charAt(j) != ';')
j++;
if (j == len || j < i + MIN_ESCAPE || j == i + MAX_ESCAPE + 1) {
i++;
continue;
}
// Found escape
if (input.charAt(i) == '#') {
// Numeric escape
int k = i + 1;
int radix = 10;
final char firstChar = input.charAt(k);
if (firstChar == 'x' || firstChar == 'X') {
k++;
radix = 16;
}
try {
int entityValue = Integer.parseInt(input.substring(k, j), radix);
if (writer == null)
writer = new StringWriter(input.length());
writer.append(input.substring(st, i - 1));
if (entityValue > 0xFFFF) {
final char[] chrs = Character.toChars(entityValue);
writer.write(chrs[0]);
writer.write(chrs[1]);
} else {
writer.write(entityValue);
}
} catch (NumberFormatException ex) {
i++;
continue;
}
}
else {
// Named escape
CharSequence value = lookupMap.get(input.substring(i, j));
if (value == null) {
i++;
continue;
}
if (writer == null)
writer = new StringWriter(input.length());
writer.append(input.substring(st, i - 1));
writer.append(value);
}
// Skip escape
st = j + 1;
i = st;
}
if (writer != null) {
writer.append(input.substring(st, len));
return writer.toString();
}
return input;
}
private static final String[][] ESCAPES = {
{"\"", "quot"}, // " - double-quote
{"&", "amp"}, // & - ampersand
{"<", "lt"}, // < - less-than
{">", "gt"}, // > - greater-than
// Mapping to escape ISO-8859-1 characters to their named HTML 3.x equivalents.
{"\u00A0", "nbsp"}, // Non-breaking space
{"\u00A1", "iexcl"}, // Inverted exclamation mark
{"\u00A2", "cent"}, // Cent sign
{"\u00A3", "pound"}, // Pound sign
{"\u00A4", "curren"}, // Currency sign
{"\u00A5", "yen"}, // Yen sign = yuan sign
{"\u00A6", "brvbar"}, // Broken bar = broken vertical bar
{"\u00A7", "sect"}, // Section sign
{"\u00A8", "uml"}, // Diaeresis = spacing diaeresis
{"\u00A9", "copy"}, // © - copyright sign
{"\u00AA", "ordf"}, // Feminine ordinal indicator
{"\u00AB", "laquo"}, // Left-pointing double angle quotation mark = left pointing guillemet
{"\u00AC", "not"}, // Not sign
{"\u00AD", "shy"}, // Soft hyphen = discretionary hyphen
{"\u00AE", "reg"}, // ® - registered trademark sign
{"\u00AF", "macr"}, // Macron = spacing macron = overline = APL overbar
{"\u00B0", "deg"}, // Degree sign
{"\u00B1", "plusmn"}, // Plus-minus sign = plus-or-minus sign
{"\u00B2", "sup2"}, // Superscript two = superscript digit two = squared
{"\u00B3", "sup3"}, // Superscript three = superscript digit three = cubed
{"\u00B4", "acute"}, // Acute accent = spacing acute
{"\u00B5", "micro"}, // Micro sign
{"\u00B6", "para"}, // Pilcrow sign = paragraph sign
{"\u00B7", "middot"}, // Middle dot = Georgian comma = Greek middle dot
{"\u00B8", "cedil"}, // Cedilla = spacing cedilla
{"\u00B9", "sup1"}, // Superscript one = superscript digit one
{"\u00BA", "ordm"}, // Masculine ordinal indicator
{"\u00BB", "raquo"}, // Right-pointing double angle quotation mark = right pointing guillemet
{"\u00BC", "frac14"}, // Vulgar fraction one quarter = fraction one quarter
{"\u00BD", "frac12"}, // Vulgar fraction one half = fraction one half
{"\u00BE", "frac34"}, // Vulgar fraction three quarters = fraction three quarters
{"\u00BF", "iquest"}, // Inverted question mark = turned question mark
{"\u00C0", "Agrave"}, // А - uppercase A, grave accent
{"\u00C1", "Aacute"}, // Б - uppercase A, acute accent
{"\u00C2", "Acirc"}, // В - uppercase A, circumflex accent
{"\u00C3", "Atilde"}, // Г - uppercase A, tilde
{"\u00C4", "Auml"}, // Д - uppercase A, umlaut
{"\u00C5", "Aring"}, // Е - uppercase A, ring
{"\u00C6", "AElig"}, // Ж - uppercase AE
{"\u00C7", "Ccedil"}, // З - uppercase C, cedilla
{"\u00C8", "Egrave"}, // И - uppercase E, grave accent
{"\u00C9", "Eacute"}, // Й - uppercase E, acute accent
{"\u00CA", "Ecirc"}, // К - uppercase E, circumflex accent
{"\u00CB", "Euml"}, // Л - uppercase E, umlaut
{"\u00CC", "Igrave"}, // М - uppercase I, grave accent
{"\u00CD", "Iacute"}, // Н - uppercase I, acute accent
{"\u00CE", "Icirc"}, // О - uppercase I, circumflex accent
{"\u00CF", "Iuml"}, // П - uppercase I, umlaut
{"\u00D0", "ETH"}, // Р - uppercase Eth, Icelandic
{"\u00D1", "Ntilde"}, // С - uppercase N, tilde
{"\u00D2", "Ograve"}, // Т - uppercase O, grave accent
{"\u00D3", "Oacute"}, // У - uppercase O, acute accent
{"\u00D4", "Ocirc"}, // Ф - uppercase O, circumflex accent
{"\u00D5", "Otilde"}, // Х - uppercase O, tilde
{"\u00D6", "Ouml"}, // Ц - uppercase O, umlaut
{"\u00D7", "times"}, // Multiplication sign
{"\u00D8", "Oslash"}, // Ш - uppercase O, slash
{"\u00D9", "Ugrave"}, // Щ - uppercase U, grave accent
{"\u00DA", "Uacute"}, // Ъ - uppercase U, acute accent
{"\u00DB", "Ucirc"}, // Ы - uppercase U, circumflex accent
{"\u00DC", "Uuml"}, // Ь - uppercase U, umlaut
{"\u00DD", "Yacute"}, // Э - uppercase Y, acute accent
{"\u00DE", "THORN"}, // Ю - uppercase THORN, Icelandic
{"\u00DF", "szlig"}, // Я - lowercase sharps, German
{"\u00E0", "agrave"}, // а - lowercase a, grave accent
{"\u00E1", "aacute"}, // б - lowercase a, acute accent
{"\u00E2", "acirc"}, // в - lowercase a, circumflex accent
{"\u00E3", "atilde"}, // г - lowercase a, tilde
{"\u00E4", "auml"}, // д - lowercase a, umlaut
{"\u00E5", "aring"}, // е - lowercase a, ring
{"\u00E6", "aelig"}, // ж - lowercase ae
{"\u00E7", "ccedil"}, // з - lowercase c, cedilla
{"\u00E8", "egrave"}, // и - lowercase e, grave accent
{"\u00E9", "eacute"}, // й - lowercase e, acute accent
{"\u00EA", "ecirc"}, // к - lowercase e, circumflex accent
{"\u00EB", "euml"}, // л - lowercase e, umlaut
{"\u00EC", "igrave"}, // м - lowercase i, grave accent
{"\u00ED", "iacute"}, // н - lowercase i, acute accent
{"\u00EE", "icirc"}, // о - lowercase i, circumflex accent
{"\u00EF", "iuml"}, // п - lowercase i, umlaut
{"\u00F0", "eth"}, // р - lowercase eth, Icelandic
{"\u00F1", "ntilde"}, // с - lowercase n, tilde
{"\u00F2", "ograve"}, // т - lowercase o, grave accent
{"\u00F3", "oacute"}, // у - lowercase o, acute accent
{"\u00F4", "ocirc"}, // ф - lowercase o, circumflex accent
{"\u00F5", "otilde"}, // х - lowercase o, tilde
{"\u00F6", "ouml"}, // ц - lowercase o, umlaut
{"\u00F7", "divide"}, // Division sign
{"\u00F8", "oslash"}, // ш - lowercase o, slash
{"\u00F9", "ugrave"}, // щ - lowercase u, grave accent
{"\u00FA", "uacute"}, // ъ - lowercase u, acute accent
{"\u00FB", "ucirc"}, // ы - lowercase u, circumflex accent
{"\u00FC", "uuml"}, // ь - lowercase u, umlaut
{"\u00FD", "yacute"}, // э - lowercase y, acute accent
{"\u00FE", "thorn"}, // ю - lowercase thorn, Icelandic
{"\u00FF", "yuml"}, // я - lowercase y, umlaut
};
private static final int MIN_ESCAPE = 2;
private static final int MAX_ESCAPE = 6;
private static final HashMap<String, CharSequence> lookupMap;
static {
lookupMap = new HashMap<String, CharSequence>();
for (final CharSequence[] seq : ESCAPES)
lookupMap.put(seq[1].toString(), seq[0]);
}
}
Kürzlich musste ich ein langsames Struts-Projekt optimieren. Es stellte sich heraus, dass Struts unter dem Deckmantel standardmäßig Apache für das HTML-String-Escape aufruft (<s:property value="..."/>
). Flucht ausschalten (<s:property value="..." escaping="false"/>
) hat dazu geführt, dass einige Seiten 5 bis 20 % schneller ausgeführt werden.
– Stephan
13. Juli 2014 um 22:10 Uhr
Später fand ich heraus, dass dieser Code in eine Schleife gelangen kann, wenn eine leere Zeichenfolge als Argument angegeben wird. In der aktuellen Ausgabe wurde dieses Problem behoben.
– Nick Frolov
17. September 2014 um 6:20
Ist das Escape oder Unespace? &Ampere; wird nicht entschlüsselt. Der Karte wird nur & hinzugefügt, es funktioniert also nur in eine Richtung?
– mjs
31. Januar 2015 um 19:29
Ein StringWriter verwendet intern einen StringBuffer, der Sperren verwendet. Die direkte Verwendung eines StringBuilder sollte schneller sein.
– Axel Dörfler
22. Februar 2016 um 12:40 Uhr
@NickFrolov, deine Kommentare scheinen etwas durcheinander zu sein. auml
ist zum Beispiel ä
und nicht д
.
– aioobe
17. Okt. 2016 um 1:52
Stephan
Die folgende Bibliothek kann auch für HTML-Escape in Java verwendet werden: unbeeindruckt.
HTML kann auf diese Weise entmaskiert werden:
final String unescapedText = HtmlEscape.unescapeHtml(escapedText);
Wenn Sie das Spring-Framework bereits verwenden, verwenden Sie die folgende Methode:
import static org.springframework.web.util.HtmlUtils.htmlUnescape;
...
String result = htmlUnescape(source);
Peter Mortensen
Das hat den Job für mich erledigt,
import org.apache.commons.lang.StringEscapeUtils;
...
String decodedXML = StringEscapeUtils.unescapeHtml(encodedXML);
Oder
import org.apache.commons.lang3.StringEscapeUtils;
...
String decodedXML = StringEscapeUtils.unescapeHtml4(encodedXML);
Ich denke, es ist immer besser, das zu verwenden lang3
aus offensichtlichen Gründen.
Peter Mortensen
Eine sehr einfache, aber ineffiziente Lösung ohne externe Bibliothek ist:
public static String unescapeHtml3(String str) {
try {
HTMLDocument doc = new HTMLDocument();
new HTMLEditorKit().read(new StringReader("<html><body>" + str), doc, 0);
return doc.getText(1, doc.getLength());
} catch(Exception ex) {
return str;
}
}
Dies sollte nur verwendet werden, wenn nur eine kleine Anzahl von Zeichenfolgen dekodiert werden muss.
Sehr nahe, aber nicht genau – es wurde „qwAS12ƷƸDžǚǪǼȌ“ in „qwAS12ƷƸDžǚǪǼȌ\n“ konvertiert.
– Gregor
16. Juli 2018 um 17:21 Uhr
wird als Zeichenentität bezeichnet. Habe den Titel bearbeitet.
– Eugene Yokota
15. Juni 2009 um 2:46