|
|
@@ -1,5 +1,6 @@
|
|
|
package cn.hutool.core.util;
|
|
|
|
|
|
+import cn.hutool.core.lang.Filter;
|
|
|
import cn.hutool.core.text.escape.Html4Escape;
|
|
|
import cn.hutool.core.text.escape.Html4Unescape;
|
|
|
|
|
|
@@ -7,57 +8,87 @@ import cn.hutool.core.text.escape.Html4Unescape;
|
|
|
* 转义和反转义工具类Escape / Unescape<br>
|
|
|
* escape采用ISO Latin字符集对指定的字符串进行编码。<br>
|
|
|
* 所有的空格符、标点符号、特殊字符以及其他非ASCII字符都将被转化成%xx格式的字符编码(xx等于该字符在字符集表里面的编码的16进制数字)。
|
|
|
- *
|
|
|
+ *
|
|
|
* @author xiaoleilu
|
|
|
*/
|
|
|
public class EscapeUtil {
|
|
|
|
|
|
/**
|
|
|
+ * 不转义的符号编码
|
|
|
+ */
|
|
|
+ private static final String NOT_ESCAPE_CHARS = "*@-_+./";
|
|
|
+ private static final Filter<Character> JS_ESCAPE_FILTER = c -> false == (
|
|
|
+ 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(String html) {
|
|
|
+ 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(String html) {
|
|
|
+ public static String unescapeHtml4(CharSequence html) {
|
|
|
Html4Unescape unescape = new Html4Unescape();
|
|
|
return unescape.replace(html).toString();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
+ * Escape编码(Unicode)(等同于JS的escape()方法)<br>
|
|
|
+ * 该方法不会对 ASCII 字母和数字进行编码,也不会对下面这些 ASCII 标点符号进行编码: * @ - _ + . / <br>
|
|
|
+ * 其他所有的字符都会被转义序列替换。
|
|
|
+ *
|
|
|
+ * @param content 被转义的内容
|
|
|
+ * @return 编码后的字符串
|
|
|
+ */
|
|
|
+ public static String escape(CharSequence content) {
|
|
|
+ return escape(content, JS_ESCAPE_FILTER);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
* Escape编码(Unicode)<br>
|
|
|
- * 该方法不会对 ASCII 字母和数字进行编码,也不会对下面这些 ASCII 标点符号进行编码: * @ - _ + . / 。其他所有的字符都会被转义序列替换。
|
|
|
- *
|
|
|
+ * 该方法不会对 ASCII 字母和数字进行编码。其他所有的字符都会被转义序列替换。
|
|
|
+ *
|
|
|
* @param content 被转义的内容
|
|
|
* @return 编码后的字符串
|
|
|
*/
|
|
|
- public static String escape(String content) {
|
|
|
- if (StrUtil.isBlank(content)) {
|
|
|
- return content;
|
|
|
+ public static String escapeAll(CharSequence content) {
|
|
|
+ return escape(content, c -> true);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Escape编码(Unicode)<br>
|
|
|
+ * 该方法不会对 ASCII 字母和数字进行编码。其他所有的字符都会被转义序列替换。
|
|
|
+ *
|
|
|
+ * @param content 被转义的内容
|
|
|
+ * @param filter 编码过滤器,对于过滤器中accept为false的字符不做编码
|
|
|
+ * @return 编码后的字符串
|
|
|
+ */
|
|
|
+ public static String escape(CharSequence content, Filter<Character> filter) {
|
|
|
+ if (StrUtil.isEmpty(content)) {
|
|
|
+ return StrUtil.str(content);
|
|
|
}
|
|
|
|
|
|
- int i;
|
|
|
+ final StringBuilder tmp = new StringBuilder(content.length() * 6);
|
|
|
char j;
|
|
|
- StringBuilder tmp = new StringBuilder();
|
|
|
- tmp.ensureCapacity(content.length() * 6);
|
|
|
-
|
|
|
- for (i = 0; i < content.length(); i++) {
|
|
|
-
|
|
|
+ for (int i = 0; i < content.length(); i++) {
|
|
|
j = content.charAt(i);
|
|
|
-
|
|
|
- if (Character.isDigit(j) || Character.isLowerCase(j) || Character.isUpperCase(j)) {
|
|
|
+ if (false == filter.accept(j)) {
|
|
|
tmp.append(j);
|
|
|
} else if (j < 256) {
|
|
|
tmp.append("%");
|
|
|
@@ -75,7 +106,7 @@ public class EscapeUtil {
|
|
|
|
|
|
/**
|
|
|
* Escape解码
|
|
|
- *
|
|
|
+ *
|
|
|
* @param content 被转义的内容
|
|
|
* @return 解码后的字符串
|
|
|
*/
|
|
|
@@ -115,7 +146,7 @@ public class EscapeUtil {
|
|
|
|
|
|
/**
|
|
|
* 安全的unescape文本,当文本不是被escape的时候,返回原文。
|
|
|
- *
|
|
|
+ *
|
|
|
* @param content 内容
|
|
|
* @return 解码后的字符串,如果解码失败返回原字符串
|
|
|
*/
|