代码之家  ›  专栏  ›  技术社区  ›  Eduardo

在Java中从字符串中筛选非MySQL Latin1字符

  •  1
  • Eduardo  · 技术社区  · 6 年前

    在将字符串插入此表之前,我想检查字符串是否包含不属于拉丁字符集的字符。这样我就可以从我的数据集中删除它。

    我该怎么做?

    例如

    boolean hasNonLatin1Chars = string.chars()
                    .anyMatch(c -> ...)
    
    3 回复  |  直到 6 年前
        1
  •  0
  •   leonbloy    6 年前

    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);
    }
    
        2
  •  0
  •   Rick James    6 年前

    把这个用在 getConnection() 电话:

    ?useUnicode=yes&characterEncoding=UTF-8
    

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

        3
  •  -1
  •   achAmháin    6 年前

    Basic Latin range 0020–007F ,因此可以检查尝试替换非拉丁字符的第一个实例是否与原始字符匹配 String :

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

    false 如果它包含非拉丁字符。

    有拉丁语-1增补( 00A0 — 00FF ),拉丁文扩展-A( 0100 — 017F )拉丁语扩展-B( 0180 — 024F )因此,您可以根据需要修改范围。