在java中从字符串中筛选非mysql latin1字符

bzzcjhmw  于 2021-06-19  发布在  Mysql
关注(0)|答案(3)|浏览(351)

我有一个mysql表,使用拉丁语1,不幸的是,我不能改变这一点。
在将字符串插入此表之前,我想检查字符串是否包含不属于拉丁字符集的字符。这样我就可以从我的数据集中删除它。
我该怎么做?
例如

boolean hasNonLatin1Chars = string.chars()
                .anyMatch(c -> ...)
a1o7rhls

a1o7rhls1#

要保持它的简单和健壮,请利用 CharsetEncoder :

/**replaces any invalid character in Latin1 by the character rep */
public static String latin1(String str, char rep) {
    CharsetEncoder cs = StandardCharsets.ISO_8859_1.newEncoder()
            .onMalformedInput(CodingErrorAction.REPLACE)
            .onUnmappableCharacter(CodingErrorAction.REPLACE)
            .replaceWith(new byte[] { (byte) rep });
    try {
        ByteBuffer b = cs.encode(CharBuffer.wrap(str));
        return new String(b.array(), StandardCharsets.ISO_8859_1);
    } catch (CharacterCodingException e) {
        throw new RuntimeException(e); // should not happen
    }
}

这将用替换字符替换iso\U 8859\U 1(=latin1)中的每个无效字符集 rep (当然,应该是一个有效的拉丁字符)。
如果您同意默认替换( '?' ),您可以简化:

public static String latin1(String str) {
    return new String(str.getBytes(StandardCharsets.ISO_8859_1),
          StandardCharsets.ISO_8859_1);
}

例如:

public static void main(String[] args)  {
    String x = "hi Œmar!";
    System.out.println("'" + x + "' -> '" + latin1(x,'?') + "'");
}

输出 'hi Œmar!' -> 'hi ?mar!' 这种方法的一个可能的缺点是只允许用一个替换字符替换每个无效字符—不能删除它或使用多字符序列。如果您想要这样做,并且有理由确信某些字符永远不会出现在您的字符串中,您可以使用常见的肮脏技巧—例如,假设 \u0000 永远不会出现:

/* removes invalid Latin1 charaters - assumes the zero character never appears */
public static String latin1removeinvalid(String str) {
    return latin1(str,(char)0).replace("\u0000", "");
}

补充:如果您只想检查有效性,那么更简单:

public static boolean isValidLatin1(String str) {
    return StandardCharsets.ISO_8859_1.newEncoder().canEncode(str);
}
eivgtgni

eivgtgni2#

拉丁语的基本范围是 0020–007F ,因此可以检查尝试替换非拉丁字符的第一个示例是否与原始字符匹配 String :

boolean hasNonLatin1Chars = string.equals((string.replaceFirst("[^\\u0020-\\u007F]", "")));

这会回来的 false 如果它包含非拉丁字符。
有拉丁语-1增补( 00A0 — 00FF ),拉丁文扩展-a( 0100 — 017F )拉丁语扩展-b( 0180 — 024F )因此,您可以根据需要修改范围。

tcbh2hod

tcbh2hod3#

如果源数据始终是utf8,那么就这样说。然后你得到了最好的两个世界-utf8字符有一个音译拉丁1将被改变;不这样做的人会被称为“?”。
把这个用在 getConnection() 电话:

?useUnicode=yes&characterEncoding=UTF-8

没有坏字符测试,没有代码转换。mysql自动完成所有的工作。

相关问题