com.dahuatech.hutool.core.util.EscapeUtil Maven / Gradle / Ivy
package com.dahuatech.hutool.core.util;
import com.dahuatech.hutool.core.lang.Filter;
import com.dahuatech.hutool.core.text.escape.Html4Escape;
import com.dahuatech.hutool.core.text.escape.Html4Unescape;
/**
* 转义和反转义工具类Escape / Unescape
* escape采用ISO Latin字符集对指定的字符串进行编码。
* 所有的空格符、标点符号、特殊字符以及其他非ASCII字符都将被转化成%xx格式的字符编码(xx等于该字符在字符集表里面的编码的16进制数字)。
*
* @author xiaoleilu
*/
public class EscapeUtil {
/** 不转义的符号编码 */
private static final String NOT_ESCAPE_CHARS = "*@-_+./";
private static final Filter JS_ESCAPE_FILTER =
new Filter() {
@Override
public boolean accept(Character c) {
return Character.isDigit(c)
|| Character.isLowerCase(c)
|| Character.isUpperCase(c)
|| StrUtil.contains(NOT_ESCAPE_CHARS, c);
}
};
/**
* 转义HTML4中的特殊字符
*
* @param html HTML文本
* @return 转义后的文本
* @since 4.1.5
*/
public static String escapeHtml4(CharSequence html) {
Html4Escape escape = new Html4Escape();
return escape.replace(html).toString();
}
/**
* 反转义HTML4中的特殊字符
*
* @param html HTML文本
* @return 转义后的文本
* @since 4.1.5
*/
public static String unescapeHtml4(CharSequence html) {
Html4Unescape unescape = new Html4Unescape();
return unescape.replace(html).toString();
}
/**
* Escape编码(Unicode)(等同于JS的escape()方法)
* 该方法不会对 ASCII 字母和数字进行编码,也不会对下面这些 ASCII 标点符号进行编码: * @ - _ + . /
* 其他所有的字符都会被转义序列替换。
*
* @param content 被转义的内容
* @return 编码后的字符串
*/
public static String escape(CharSequence content) {
return escape(content, JS_ESCAPE_FILTER);
}
/**
* Escape编码(Unicode)
* 该方法不会对 ASCII 字母和数字进行编码。其他所有的字符都会被转义序列替换。
*
* @param content 被转义的内容
* @return 编码后的字符串
*/
public static String escapeAll(CharSequence content) {
return escape(
content,
new Filter() {
@Override
public boolean accept(Character character) {
return true;
}
});
}
/**
* Escape编码(Unicode)
* 该方法不会对 ASCII 字母和数字进行编码。其他所有的字符都会被转义序列替换。
*
* @param content 被转义的内容
* @param filter 编码过滤器,对于过滤器中accept为false的字符不做编码
* @return 编码后的字符串
*/
public static String escape(CharSequence content, Filter filter) {
if (StrUtil.isEmpty(content)) {
return StrUtil.str(content);
}
final StringBuilder tmp = new StringBuilder(content.length() * 6);
char j;
for (int i = 0; i < content.length(); i++) {
j = content.charAt(i);
if (false == filter.accept(j)) {
tmp.append(j);
} else if (j < 256) {
tmp.append("%");
if (j < 16) {
tmp.append("0");
}
tmp.append(Integer.toString(j, 16));
} else {
tmp.append("%u");
tmp.append(Integer.toString(j, 16));
}
}
return tmp.toString();
}
/**
* Escape解码
*
* @param content 被转义的内容
* @return 解码后的字符串
*/
public static String unescape(String content) {
if (StrUtil.isBlank(content)) {
return content;
}
StringBuilder tmp = new StringBuilder(content.length());
int lastPos = 0;
int pos;
char ch;
while (lastPos < content.length()) {
pos = content.indexOf("%", lastPos);
if (pos == lastPos) {
if (content.charAt(pos + 1) == 'u') {
ch = (char) Integer.parseInt(content.substring(pos + 2, pos + 6), 16);
tmp.append(ch);
lastPos = pos + 6;
} else {
ch = (char) Integer.parseInt(content.substring(pos + 1, pos + 3), 16);
tmp.append(ch);
lastPos = pos + 3;
}
} else {
if (pos == -1) {
tmp.append(content.substring(lastPos));
lastPos = content.length();
} else {
tmp.append(content, lastPos, pos);
lastPos = pos;
}
}
}
return tmp.toString();
}
/**
* 安全的unescape文本,当文本不是被escape的时候,返回原文。
*
* @param content 内容
* @return 解码后的字符串,如果解码失败返回原字符串
*/
public static String safeUnescape(String content) {
try {
return unescape(content);
} catch (Exception e) {
// Ignore Exception
}
return content;
}
}