Về cơ bản, tôi muốn giải mã một tài liệu Html đã cho và thay thế tất cả các ký tự đặc biệt, chẳng hạn như " "
-> " "
, ">"
-> ">"
.
Trong .NET chúng ta có thể sử dụng HttpUtility.HtmlDecode
.
Hàm tương đương trong Java là gì?
Về cơ bản, tôi muốn giải mã một tài liệu Html đã cho và thay thế tất cả các ký tự đặc biệt, chẳng hạn như " "
-> " "
, ">"
-> ">"
.
Trong .NET chúng ta có thể sử dụng HttpUtility.HtmlDecode
.
Hàm tương đương trong Java là gì?
Câu trả lời:
Tôi đã sử dụng Apache Commons StringEscapeUtils.unescapeHtml4 () cho việc này:
Hủy bỏ một chuỗi chứa thực thể thoát thành một chuỗi chứa các ký tự Unicode thực tế tương ứng với các thoát. Hỗ trợ các thực thể HTML 4.0.
<p>üè</p>
thành <p>üé</p>
, với StringEscapeUtils.unescapeHtml4()
tôi nhận được <p>üè</p>
. Có cách nào để giữ nguyên các thẻ html hiện tại không?
Các thư viện được đề cập trong các câu trả lời khác sẽ là giải pháp tốt, nhưng nếu bạn đã tình cờ tìm hiểu về html thế giới thực trong dự án của bạn, thì Jsoup
dự án có nhiều thứ để cung cấp hơn là chỉ quản lý những thứ "dấu chấm phẩy 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);
Và bạn cũng có được API thuận tiện để trích xuất và thao tác dữ liệu, sử dụng các phương thức tốt nhất của DOM, CSS và jquery. Đó là mã nguồn mở và giấy phép MIT.
.text()
thay vì.getText()
org.jsoup.parser.Parser.unescapeEntities(String string, boolean inAttribute)
. Tài liệu API: jsoup.org/apidocs/org/jsoup/parser/ triệt
Tôi đã thử Apache Commons StringEscapeUtils.unescapeHtml3 () trong dự án của mình, nhưng không hài lòng với hiệu suất của nó. Hóa ra, nó làm rất nhiều thao tác không cần thiết. Đối với một, nó phân bổ StringWriter cho mỗi cuộc gọi, ngay cả khi không có gì để unescape trong chuỗi. Tôi đã viết lại mã đó theo cách khác, bây giờ nó hoạt động nhanh hơn nhiều. Bất cứ ai tìm thấy điều này trong google đều được chào đón để sử dụng nó.
Mã theo sau hủy bỏ tất cả các ký hiệu HTML 3 và thoát số (tương đương với Apache unescapeHtml3). Bạn chỉ có thể thêm nhiều mục vào bản đồ nếu bạn cần 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="..."/>
). Tắt thoát ( <s:property value="..." escaping="false"/>
) có một số trang để chạy nhanh hơn 5% đến 20%.
auml
là ví dụ ä
và không д
.
Thư viện sau đây cũng có thể được sử dụng để thoát HTML trong Java: unbescape .
HTML có thể được bỏ qua theo cách này:
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
Điều này đã làm công việc cho tôi,
import org.apache.commons.lang.StringEscapeUtils;
...
String decodedXML= StringEscapeUtils.unescapeHtml(encodedXML);
hoặc là
import org.apache.commons.lang3.StringEscapeUtils;
...
String decodedXML= StringEscapeUtils.unescapeHtml4(encodedXML);
Tôi đoán nó luôn luôn tốt hơn để sử dụng lang3
cho các lý do rõ ràng. Hi vọng điêu nay co ich :)
Một giải pháp rất đơn giản nhưng không hiệu quả mà không cần bất kỳ thư viện bên ngoài nào là:
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;
}
}
Điều này chỉ nên được sử dụng nếu bạn chỉ có một số lượng nhỏ chuỗi để giải mã.
Cách đáng tin cậy nhất là với
String cleanedString = StringEscapeUtils.unescapeHtml4(originalString);
từ org.apache.commons.lang3.StringEscapeUtils
.
Và để thoát khỏi khoảng trắng
cleanedString = cleanedString.trim();
Điều này sẽ đảm bảo rằng các khoảng trắng do sao chép và dán vào các biểu mẫu web để không bị tồn tại trong DB.
Nếu bạn đã sử dụng Spring framework, hãy sử dụng phương pháp sau:
import static org.springframework.web.util.HtmlUtils.htmlUnescape;
...
String result = htmlUnescape(source);
Xem xét sử dụng lớp Java HtmlManipulator . Bạn có thể cần thêm một số mục (không phải tất cả các thực thể đều có trong danh sách).
StringEscapeUtils của Apache như được đề xuất bởi Kevin Hakanson đã không hoạt động 100% với tôi; một số thực thể như & # 145 (trích dẫn đơn bên trái) đã được dịch thành '222' bằng cách nào đó. Tôi cũng đã thử org.jsoup và gặp vấn đề tương tự.
Trong trường hợp của tôi, tôi sử dụng phương thức thay thế bằng cách kiểm tra mọi thực thể trong mọi biến, mã của tôi trông như thế này:
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("ú", "ú");
Trong trường hợp của tôi, điều này làm việc rất tốt.
Trong trường hợp bạn muốn bắt chước chức năng php htmlspecialchars_decode nào sử dụng hàm php get_html_translation_table () để kết xuất bảng và sau đó sử dụng mã java như,
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;
}