Wie kann ich HTML-Zeichenentitäten in Java deaktivieren?

Lesezeit: 9 Minuten

Benutzeravatar von yinyueyouge
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?

  •   wird als Zeichenentität bezeichnet. Habe den Titel bearbeitet.

    – Eugene Yokota

    15. Juni 2009 um 2:46

Kevin Hakansons Benutzeravatar
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>&uuml;&egrave;</p> Zu <p>üé</p>mit StringEscapeUtils.unescapeHtml4() Ich bekomme &lt;p&gt;üè&lt;/p&gt;. Gibt es eine Möglichkeit, vorhandene HTML-Tags intakt zu halten?

    – Nickkk

    13. Januar 2020 um 12:10 Uhr

  • Wenn ich so etwas habe &#147; 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

Dales Benutzeravatar
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&nbsp;sample. \"Granny\" Smith &#8211;.<\/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 Frolovs Benutzeravatar
Nick Frolov

Ich habe es versucht Apache CommonsStringEscapeUtils.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

Stephans Benutzeravatar
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); 

Spring Framework HtmlUtils

Wenn Sie das Spring-Framework bereits verwenden, verwenden Sie die folgende Methode:

import static org.springframework.web.util.HtmlUtils.htmlUnescape;

...

String result = htmlUnescape(source);

Benutzer-Avatar von Peter Mortensen
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.

Benutzer-Avatar von Peter Mortensen
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


1454290cookie-checkWie kann ich HTML-Zeichenentitäten in Java deaktivieren?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy