17

我有脏数据。有时它包含这样的字符。我使用这些数据进行查询,例如

WHERE a.address IN ('mydatahere')

对于这个角色,我得到

org.hibernate.exception.GenericJDBCException:非法混合排序规则(utf8_bin,IMPLICIT),(utf8mb4_general_ci,COERCIBLE),(utf8mb4_general_ci,COERCIBLE)用于操作'IN'

我怎样才能过滤掉这样的字符?我使用Java。

谢谢。

4

6 回答 6

10
于 2012-12-01T07:26:28.523 回答
7

您可以对其进行编码,然后将其解码为 UTF-8:

String label = "look into my eyes 〠.〠";

Charset charset = Charset.forName("UTF-8");
label = charset.decode(charset.encode(label)).toString();

System.out.println(label);

输出:

look into my eyes ?.?

编辑:我认为这可能只适用于 Java 6。

于 2014-07-17T04:53:37.150 回答
3

您可以使用此正则表达式过滤代理字符:

String str  = ""; //U+20000, represented by 2 chars in java (UTF-16 surrogate pair)
str = str.replaceAll( "([\\ud800-\\udbff\\udc00-\\udfff])", "");
System.out.println(str.length()); //0
于 2012-12-01T08:12:38.623 回答
2

在 java 机器上将字节数组转换为 String 后,您将获得(在大多数机器上默认情况下)UTF-16 编码的字符串。摆脱非 UTF-8 字符的正确解决方案是使用以下代码:

String[] values = {"\\xF0\\x9F\\x98\\x95", "\\xF0\\x9F\\x91\\x8C", "/*", "look into my eyes 〠.〠", "fkdjsf ksdjfslk", "\\xF0\\x80\\x80\\x80", "aa \\xF0\\x9F\\x98\\x95 aa", "Ok"};
for (int i = 0; i < values.length; i++) {
    System.out.println(values[i].replaceAll(
                    //"[\\\\x00-\\\\x7F]|" + //single-byte sequences   0xxxxxxx - commented because of capitol letters
                    "[\\\\xC0-\\\\xDF][\\\\x80-\\\\xBF]|" + //double-byte sequences   110xxxxx 10xxxxxx
                    "[\\\\xE0-\\\\xEF][\\\\x80-\\\\xBF]{2}|" + //triple-byte sequences   1110xxxx 10xxxxxx * 2
                    "[\\\\xF0-\\\\xF7][\\\\x80-\\\\xBF]{3}" //quadruple-byte sequence 11110xxx 10xxxxxx * 3
            , ""));
}

或者,如果您想验证某个字符串是否包含非 utf8 字符,您可以使用 Pattern.matches,例如:

String[] values = {"\\xF0\\x9F\\x98\\x95", "\\xF0\\x9F\\x91\\x8C", "/*", "look into my eyes 〠.〠", "fkdjsf ksdjfslk", "\\xF0\\x80\\x80\\x80", "aa \\xF0\\x9F\\x98\\x95 aa", "Ok"};
for (int i = 0; i < values.length; i++) {
    System.out.println(Pattern.matches(
                    ".*(" +
                    //"[\\\\x00-\\\\x7F]|" + //single-byte sequences   0xxxxxxx - commented because of capitol letters
                    "[\\\\xC0-\\\\xDF][\\\\x80-\\\\xBF]|" + //double-byte sequences   110xxxxx 10xxxxxx
                    "[\\\\xE0-\\\\xEF][\\\\x80-\\\\xBF]{2}|" + //triple-byte sequences   1110xxxx 10xxxxxx * 2
                    "[\\\\xF0-\\\\xF7][\\\\x80-\\\\xBF]{3}" //quadruple-byte sequence 11110xxx 10xxxxxx * 3
                    + ").*"
            , values[i]));
}

要使整个 Web 应用程序与 UTF8 兼容,请阅读此处:
如何在 Java webapps 中使用 UTF-8
更多关于字节编码和字符串你可以在这里
检查你的模式。 在 PHP 中也是如此

于 2015-05-27T11:44:54.530 回答
-1

可能这会帮助某人,因为它帮助了我。

public static String removeBadChars(String s) {
  if (s == null) return null;
  StringBuilder sb = new StringBuilder();
  for(int i=0;i<s.length();i++){ 
    if (Character.isHighSurrogate(s.charAt(i))) continue;
    sb.append(s.charAt(i));
  }
  return sb.toString();
}
于 2012-12-01T09:11:12.110 回答
-1

在 PHP 中 - 我只允许可打印数据来解决这个问题。这确实有助于清理数据库的数据。
虽然它是预处理,但有时你没有那么奢侈。

$str = preg_replace('/[[:^print:]]/', '', $str);
于 2019-12-16T15:29:24.070 回答