기본적으로 주어진 Html 문서를 해독하고 " "
-> " "
, ">"
-> 와 같은 모든 특수 문자를 바꿉니다 ">"
.
.NET에서는을 사용할 수 있습니다 HttpUtility.HtmlDecode
.
Java에서 동등한 기능은 무엇입니까?
기본적으로 주어진 Html 문서를 해독하고 " "
-> " "
, ">"
-> 와 같은 모든 특수 문자를 바꿉니다 ">"
.
.NET에서는을 사용할 수 있습니다 HttpUtility.HtmlDecode
.
Java에서 동등한 기능은 무엇입니까?
답변:
나는 이것을 위해 Apache Commons StringEscapeUtils.unescapeHtml4 () 를 사용했다.
엔티티 이스케이프가 포함 된 문자열을 이스케이프하면 이스케이프에 해당하는 실제 유니 코드 문자가 포함 된 문자열로 이스케이프됩니다. HTML 4.0 엔티티를 지원합니다.
<p>üè</p>
에를 <p>üé</p>
로 StringEscapeUtils.unescapeHtml4()
내가 얻을 <p>üè</p>
. 기존 HTML 태그를 그대로 유지하는 방법이 있습니까?
다른 답변에서 언급 된 라이브러리는 훌륭한 솔루션이지만 프로젝트에서 실제 html을 이미 파고 들었다면 Jsoup
프로젝트는 "암페어 앤 파운드 FFFF 세미콜론" 항목을 관리하는 것보다 더 많은 것을 제공 해야합니다.
// 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 라이센스입니다.
.text()
대신.getText()
org.jsoup.parser.Parser.unescapeEntities(String string, boolean inAttribute)
입니다. API 문서 : jsoup.org/apidocs/org/jsoup/parser/…
내 프로젝트에서 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]);
}
}
<s:property value="..."/>
). 이스케이프 기능 ( <s:property value="..." escaping="false"/>
)을 끄면 일부 페이지가 5 ~ 20 % 더 빨리 실행됩니다.
auml
예를 들어 ä
아닙니다 д
.
Java에서 HTML 이스케이프 처리를 위해 다음 라이브러리를 사용할 수도 있습니다. unbescape .
이 방법으로 HTML을 이스케이프 해제 할 수 있습니다.
final String unescapedText = HtmlEscape.unescapeHtml(escapedText);
%3Chtml%3E%0D%0A%3Chead%3E%0D%0A%3Ctitle%3Etest%3C%2Ftitle%3E%0D%0A%3C%2Fhead%3E%0D%0A%3Cbody%3E%0D%0Atest%0D%0A%3C%2Fbody%3E%0D%0A%3C%2Fhtml%3E
이것은 나를 위해 일을했다.
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;
}
}
디코딩 할 문자열 수가 적은 경우에만 사용해야합니다.
HtmlManipulator Java 클래스 사용을 고려하십시오 . 일부 항목을 추가해야 할 수도 있습니다 (모든 항목이 목록에있는 것은 아님).
Kevin Hakanson이 제안한 Apache Commons StringEscapeUtils는 100 % 작동하지 않았습니다. & # 145 (왼쪽 작은 따옴표)와 같은 여러 엔티티가 어떻게 든 '222'로 변환되었습니다. 나는 또한 org.jsoup을 시도했지만 같은 문제가있었습니다.
필자의 경우 모든 변수의 모든 엔티티를 테스트하여 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("ó", "ó");
text = text.replace("ú", "ú");
제 경우에는 이것이 아주 잘 작동했습니다.
htmlspecialchars_decode가 php 함수 get_html_translation_table ()을 사용하여 테이블을 덤프 한 다음 Java 코드를 사용하는 PHP 함수를 모방하려는 경우,
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;
}