자바에서 HTML 문자 엔티티를 해제하려면 어떻게 해야 합니까?
기본적으로 주어진 HTML 문서를 디코딩하고 다음과 같은 모든 특수 문자를 대체하고 싶습니다." "
→" "
그리고.">"
→">"
.
.NET에서는 HttpUtility를 사용할 수 있습니다.HtmlDecode 메서드입니다.
자바에서 그에 상응하는 기능은 무엇입니까?
Apache Commons StringEscapeUtils.unescapeHtml4()를 사용하여 다음 작업을 수행했습니다.
엔티티를 포함하는 문자열 이스케이프를 이스케이프에 해당하는 실제 유니코드 문자가 포함된 문자열로 이스케이프를 해제합니다.HTML 4.0 엔티티를 지원합니다.
다른 답변에 언급된 라이브러리는 좋은 해결책이 될 수 있지만, 프로젝트에서 이미 실제 HTML 콘텐츠를 살펴보고 있다면 프로젝트는 단순히 "앰퍼샌드 파운드 FFF 세미콜론"을 관리하는 것 이상의 많은 것을 제공합니다.
// 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);
또한 DOM, CSS 및 jQuery와 유사한 최상의 방법을 사용하여 데이터를 추출하고 조작할 수 있는 편리한 API를 얻을 수 있습니다.오픈 소스와 MIT 라이선스입니다.
프로젝트에서 Apache Commons의 StringEscapeUtils.unescapeHtml3()를 사용해 보았지만 성능에 만족하지 못했습니다.불필요한 수술을 많이 한다는 것이 밝혀졌습니다.우선 문자열에서 빠져나올 수 있는 것이 없는 경우에도 모든 호출에 StringWriter를 할당합니다.저는 그 코드를 다르게 다시 작성했고, 지금은 훨씬 더 빨리 작동합니다.
다음 코드는 모든 HTML 3 기호 및 숫자 이스케이프를 해제합니다(Apache unescapeHtml3과 동일).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]);
}
}
다음 라이브러리는 Java에서 HTML 이스케이프에 사용할 수도 있습니다: unbescape.
HTML은 다음과 같은 방법으로 이스케이프 해제할 수 있습니다.
final String unescapedText = HtmlEscape.unescapeHtml(escapedText);
Spring Framework HtmlUtils
Spring 프레임워크를 이미 사용 중인 경우 다음 방법을 사용합니다.
import static org.springframework.web.util.HtmlUtils.htmlUnescape;
...
String result = htmlUnescape(source);
이 일은 나에게 효과가 있었습니다.
import org.apache.commons.lang.StringEscapeUtils;
...
String decodedXML = StringEscapeUtils.unescapeHtml(encodedXML);
또는
import org.apache.commons.lang3.StringEscapeUtils;
...
String decodedXML = StringEscapeUtils.unescapeHtml4(encodedXML);
나는 항상 그것을 사용하는 것이 더 좋다고 생각합니다.lang3
명백한 이유로
외부 라이브러리가 없는 매우 간단하지만 비효율적인 솔루션은 다음과 같습니다.
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;
}
}
디코딩할 문자열 수가 적은 경우에만 사용해야 합니다.
가장 신뢰할 수 있는 방법은
String cleanedString = StringEscapeUtils.unescapeHtml4(originalString);
org.apache.commons.lang3.StringEscapeUtils
.
그리고 하얀 공간을 탈출하기 위해
cleanedString = cleanedString.trim();
이렇게 하면 웹 양식의 복사 및 붙여넣기로 인한 공백이 DB에 지속되지 않습니다.
문자열 이스케이프 유틸리티(Apache Commons Lang)
Java, JavaScript, HTML 및 XML에 대한 문자열을 이스케이프 및 이스케이프 해제합니다.
import org.apache.commons.lang.StringEscapeUtils;
....
StringEscapeUtils.unescapeHtml(comment);
HtmlManipulator Java 클래스를 사용해 보십시오.일부 항목을 추가해야 할 수도 있습니다(모든 엔티티가 목록에 있는 것은 아님).
케빈 하칸슨이 제안한 Apache Commons StringEscapeUtils는 저에게 100% 작동하지 않았습니다. ‘(왼쪽 단일 인용문)와 같은 여러 엔티티가 어떻게든 '222'로 번역되었습니다.저도 org.jsoup을 해봤는데 같은 문제가 있었습니다.
저의 경우 모든 변수의 모든 엔터티를 테스트하여 대체 방법을 사용합니다.내 코드는 다음과 같습니다.
text = text.replace("Ç", "Ç");
text = text.replace("ç", "ç");
text = text.replace("Á", "Á");
text = text.replace("Â", "Â");
text = text.replace("Ã", "Ã");
text = text.replace("É", "É");
text = text.replace("Ê", "Ê");
text = text.replace("Í", "Í");
text = text.replace("Ô", "Ô");
text = text.replace("Õ", "Õ");
text = text.replace("Ó", "Ó");
text = text.replace("Ú", "Ú");
text = text.replace("á", "á");
text = text.replace("â", "â");
text = text.replace("ã", "ã");
text = text.replace("é", "é");
text = text.replace("ê", "ê");
text = text.replace("í", "í");
text = text.replace("ô", "ô");
text = text.replace("õ", "õ");
text = text.replace("ó", "ó");
text = text.replace("ú", "ú");
저의 경우에는 이것이 매우 잘 작동했습니다.
만약 당신이 PHP 함수 htmlsspecialchars_decode()가 하는 것을 모방하고 싶다면, PHP 함수 get_html_translation_table()을 사용하여 테이블을 덤프하고 다음과 같은 자바 코드를 사용합니다.
static Map<String, String> html_specialchars_table = new Hashtable<String, String>();
static {
html_specialchars_table.put("<", "<");
html_specialchars_table.put(">", ">");
html_specialchars_table.put("&", "&");
}
static String htmlspecialchars_decode_ENT_NOQUOTES(String s) {
Enumeration en = html_specialchars_table.keys();
while(en.hasMoreElements()) {
String key = en.nextElement();
String val = html_specialchars_table.get(key);
s = s.replaceAll(key, val);
}
return s;
}
언급URL : https://stackoverflow.com/questions/994331/how-can-i-unescape-html-character-entities-in-java
'code' 카테고리의 다른 글
lodash 다중 열 정렬 기준 (0) | 2023.08.06 |
---|---|
Android는 .apk 파일을 보관합니까?만약 그렇다면 어디에? (0) | 2023.08.06 |
패키지에 나열된 모든 종속성을 제거하는 방법은 무엇입니까?json(NPM)? (0) | 2023.08.01 |
XML 파일 내용을 업데이트하는 PowerShell 스크립트 (0) | 2023.08.01 |
Linux에서 조건 연산자의 이상한 사용 (0) | 2023.08.01 |