Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何删除MySQL中不适合utf8编码的坏字符?_Java_Mysql_Unicode_Utf 8 - Fatal编程技术网

Java 如何删除MySQL中不适合utf8编码的坏字符?

Java 如何删除MySQL中不适合utf8编码的坏字符?,java,mysql,unicode,utf-8,Java,Mysql,Unicode,Utf 8,我有肮脏的数据。有时它包含像这样的字符。我使用这些数据进行如下查询 WHERE a.address IN ('mydatahere') 对于这个角色,我得到了 org.hibernate.exception.genericjdbception:为“IN”操作非法混合排序规则(utf8\u-bin,隐式),(utf8mb4\u-general\u-ci,可强制),(utf8mb4\u-general\u-ci,可强制) 我怎样才能过滤掉这样的字符?我使用Java 谢谢。当我遇到这样的问题时,我使

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

WHERE a.address IN ('mydatahere')
对于这个角色,我得到了

org.hibernate.exception.genericjdbception:为“IN”操作非法混合排序规则(utf8\u-bin,隐式),(utf8mb4\u-general\u-ci,可强制),(utf8mb4\u-general\u-ci,可强制)

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


谢谢。

当我遇到这样的问题时,我使用Perl脚本确保数据通过以下代码转换为有效的UTF-8:

use Encode;
binmode(STDOUT, ":utf8");
while (<>) {
    print Encode::decode('UTF-8', $_);
}

编辑:添加了纯Java解决方案

这是一个如何在Java中执行此操作的示例:

import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CodingErrorAction;

public class UtfFix {
    public static void main(String[] args) throws InterruptedException, CharacterCodingException {
        CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder();
        decoder.onMalformedInput(CodingErrorAction.REPLACE);
        decoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
        ByteBuffer bb = ByteBuffer.wrap(new byte[] {
            (byte) 0xD0, (byte) 0x9F, // 'П'
            (byte) 0xD1, (byte) 0x80, // 'р'
            (byte) 0xD0,              // corrupted UTF-8, was 'и'
            (byte) 0xD0, (byte) 0xB2, // 'в'
            (byte) 0xD0, (byte) 0xB5, // 'е'
            (byte) 0xD1, (byte) 0x82  // 'т'
        });
        CharBuffer parsed = decoder.decode(bb);
        System.out.println(parsed);
        // this prints: Пр?вет
    }
}

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

String str  = "May be this will help someone as it helped me.     

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();
}

String str=“可能这会像帮助我一样帮助别人

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

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

System.out.println(label);
公共静态字符串removeBadChars(字符串s){
如果(s==null)返回null;
StringBuilder sb=新的StringBuilder();

对于(int i=0;i,您可以对其进行编码,然后从UTF-8对其进行解码:

look into my eyes ?.?
输出:

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
            , ""));
}

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

一旦在Java机器上将字节数组转换为字符串,就会得到(在大多数机器上默认情况下)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(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]));
}
String[]value={“\\xF0\\x9F\\x98\\x95”、“\\xF0\\x9F\\x91\\x8C”、“/*”、“看着我的眼睛”、“fkdjsf ksdjfslk”、“\\xF0\\x80\\x80\\x80”、“\\xF0\\x9F\\x98\\x95 aa”、“Ok”;
对于(int i=0;i
或者,如果要验证某些字符串是否包含非utf8字符,则可以使用Pattern.matches,如:

$str = preg_replace('/[[:^print:]]/', '', $str);
String[]value={“\\xF0\\x9F\\x98\\x95”、“\\xF0\\x9F\\x91\\x8C”、“/*”、“看着我的眼睛”、“fkdjsf ksdjfslk”、“\\xF0\\x80\\x80\\x80”、“\\xF0\\x9F\\x98\\x95 aa”、“Ok”;
对于(int i=0;i
要使整个web应用程序与UTF8兼容,请阅读此处:

.
您可以检查您的模式。

在PHP中也是如此。

在PHP中,我通过只允许可打印数据来实现这一点。这确实有助于清理数据库中的数据。
不过,这是预处理的,有时你没有那种奢侈


抱歉,我需要java解决方案。您需要一个具有相同替换行为的CharsetEncoder,首先获取输入字符串的字节,然后再将其解码回字符串。在本例中,您需要将ByteBuffer替换为源代码中的实际字节流-是文本文件还是SQL列。本例的要点是如何确保您的UTF-8流绝对符合UTF-8。这取决于您如何将这些数据准确地输入到
ByteBuffer
ByteArrayInputStream
中。请注意,如果您需要读卡器,而不是像Java 7那样直接处理缓冲区,可以接受预先配置的
CharsetDecoder
,如中所示。为什么Java解决方案n不使用?而不是unicode替换字符?更糟糕的是,所有文档都指示默认替换字符为\uFFFD…可能是错误?(注意,这将删除所有代理项的使用,而不仅仅是无效序列。)@bobince是的,我想到的是MySQL,afaik在BMP以外的字符方面有问题。啊,是的-你必须使用utfmb4来存储星体平面,这是相对较新的(好吧,除非你只是将所有内容转储到二进制字符串中或使用误导性编码,这样你就不会得到Unicode感知字符串排序的好处。)dc00不是紧跟在dbff之后吗?为什么不能是“([\\ud800-\\udfff])您想删除那些
IsLowUrrogate()
的字符串。如果您的字符串有一个有效的>BMP字符,我想这会使字符串损坏。您能解释一下“由于大写字母而被注释掉”的原因吗“嗯,您刚刚删除了完全有效的Unicode字符”〠.〠”使用这个方法。问题是如何只替换无效字符,而不是全部。刚刚测试过,它提供了
看在眼里〠。〠
输出,这是正确的,因为该代码不应该导致Unicode字符丢失,除非您对Java源文件使用ASCII。
$str = preg_replace('/[[:^print:]]/', '', $str);