-1

问题

如果有时编码看起来像“UTF-8”、“UTF-16”和“ASCII”,我怎样才能只得到字符串的 5 个字符?

注意:一些测试输入有表情符号。

代码

    public String truncate(String input) {
        if (input.codePointCount(0, input.length()) > 5)
        {
            return input.substring(0, input.offsetByCodePoints(0, 5));
        }

        return input;
    }

例如:

输入:Bärteppich

预期输出:BГ¤rte也意味着Bärte

实际输出:BГ¤rt

输入:brühe

预期输出:brГјhe也意味着brühe

实际输出:brГјh

4

2 回答 2

0

首先,出于所有目的,Java始终是 UTF-16,尽管从 Java 9 开始,它可能在内部String是别的东西。

要实现您想要的(“仅从输入字符串中获取前五个字符!”),它应该如下所示:

public String truncate( String input ) 
{
    var retValue = (input != null) && (input.length() > 5)
        ? input.substring( 0, 5 )
        : input;

        return retValue;
}

应该没有必要为这个特定的任务使用代码点。

不幸的是,这并不完全正确。

它适用于 String s = "Dies ist ein langer String";

它不适用于s = "12345678";.

不幸的是,String.offsetByCodePoints()在这里没有帮助;使用问题中的原始代码时,如下所示:

public String truncate( String input ) 
{
    int x = 5;
    if( input.codePointCount( 0, input.length() ) > 5 )
    {
        return input.substring( 0, input.offsetByCodePoints( 0, x ) );
    }

    return input;
}

的正确值x取决于字符串的内容。

这是因为计算两个代码点,while 只是一个 - 并且两者都不止一个char

所以这个也失败了:

public String truncate( String input ) 
{
    var retValue = input;
    if( input.codePointCount( 0, input.length() ) > 5 )
    {
        int [] codepoints = input.codePoints().limit( 5 ).toArray();
        retValue = new String( codepoints, 0, 5 );
    }
    return retValue;
}

在这里我被卡住了……</p>

于 2020-07-01T14:40:22.677 回答
-1

如果字符串有效并且包含代码点,传递给的长度offsetByCodePoints应该是 5 而不是 6,以便在 5 个代码点位置的末尾拆分字符串?

public String truncate(String input) {
    if (input.codePointCount(0, input.length()) > 5)
    {
        input = input.substring(0, input.offsetByCodePoints(0, 5));
    }

    return input;
}
于 2020-07-01T16:27:18.840 回答