文字列の長さに基づいて文字列をトリミングする


136

文字数が10文字を超える場合、文字列をトリミングしたい。

文字列の長さが12(String s="abcdafghijkl")の場合、新しいトリミングされた文字列にはが含まれると仮定します"abcdefgh.."

どうすればこれを達成できますか?



FYI、水平の反復記号は、単一の文字ではなく、2つのまたは3であるFULL STOPの文字は:...
バジルボーク

回答:


262
s = s.substring(0, Math.min(s.length(), 10));

このMath.minように使用することで、文字列がすでにより短い場合の例外を回避できます10


ノート:

  1. 上記は実際のトリミングを行います。最後の3文字(!)を切り捨ててドットに置き換える場合は、Apache Commonsを使用してくださいStringUtils.abbreviate

  2. これが正しく動作する1を、あなたの文字列が外BMPのUnicodeのコードポイントが含まれている場合は、例:絵文字。すべてのUnicodeコードポイントで正しく機能する(より複雑な)ソリューションについては、@ sibnickのソリューションを参照してください。


1-プレーン0にないUnicodeコードポイント(BMP)は、「サロゲートペア」(つまり2つのchar値)として表されますString。これを無視すると、コードポイントを10個未満にトリミングしたり、サロゲートペアの途中で(さらに悪いことに)切り捨てたりする可能性があります。一方、String.length()はUnicodeテキストの長さの理想的な尺度ではなくなったため、それに基づいてトリミングするのは間違っているかもしれません。


Math.minの代わりに、条件チェックを実行して、文字列が最大である場合にのみ必要な部分文字列を実行することはできませんか?例:s = (s.length() > 10) ? s.substring(0,10) : s ;
rram

1
はい、もちろんできます。問題を解決する他の方法については、他の回答を読んでください!
スティーブンC

132

StringUtils.abbreviateApache Commons Langライブラリからあなたの友達になることができます:

StringUtils.abbreviate("abcdefg", 6) = "abc..."
StringUtils.abbreviate("abcdefg", 7) = "abcdefg"
StringUtils.abbreviate("abcdefg", 8) = "abcdefg"
StringUtils.abbreviate("abcdefg", 4) = "a..."

Commons Lang3では、カスタムストリングを置換マーカーとして設定することもできます。これにより、たとえば、単一の文字の省略記号を設定できます。

StringUtils.abbreviate("abcdefg", "\u2026", 6) = "abcde…"

5
可能性はありますが、OPの質問は「省略」を要求しません。
スティーブンC

9
@StephenC-質問は、長さが10に制限されている場合、8文字の後に2ドットが続くことを示します。これは省略記号に非常によく似ています(3ではなく2ドット)。また、この質問を見つけた人々の多くは、省略記号が有用であると考えるでしょう。
ToolmakerSteve

12
...そして省略記号が不要な場合は、StringUtils.left()が役立ちます。
スーパーロール

1
ちなみに水平方向の省略記号は単一の文字であり、3つのフルストップ文字ではありません。…
バジル

53

これを行うApache Commons StringUtils関数があります。

s = StringUtils.left(s, 10)

len文字が使用できない場合、または文字列がnullの場合、文字列は例外なく返されます。lenが負の場合、空の文字列が返されます。

StringUtils.left(null、)= null
StringUtils.left(
、-ve)= ""
StringUtils.left( ""、*)= ""
StringUtils.left( "abc"、0)= ""
StringUtils.left( " abc "、2)=" ab "
StringUtils.left(" abc "、4)=" abc "

StringUtils.Left JavaDocs

礼儀:スティーブ・マッコーリー


22

いつものように、誰もUTF-16サロゲートペアを気にしません。それらについて見てください:実際に使用されている最も一般的な非BMP Unicode文字は何ですか?org.apache.commons / commons-lang3の作者でさえ

このサンプルでは、​​正しいコードと通常のコードの違いを確認できます。

public static void main(String[] args) {
    //string with FACE WITH TEARS OF JOY symbol
    String s = "abcdafghi\uD83D\uDE02cdefg";
    int maxWidth = 10;
    System.out.println(s);
    //do not care about UTF-16 surrogate pairs
    System.out.println(s.substring(0, Math.min(s.length(), maxWidth)));
    //correctly process UTF-16 surrogate pairs
    if(s.length()>maxWidth){
        int correctedMaxWidth = (Character.isLowSurrogate(s.charAt(maxWidth)))&&maxWidth>0 ? maxWidth-1 : maxWidth;
        System.out.println(s.substring(0, Math.min(s.length(), correctedMaxWidth)));
    }
}

1
Apache commonsのjiraにバグが見つかりました。issues.apache.org/ jira
Ryan Quinn

10

s = s.length() > 10 ? s.substring(0, 9) : s;


16
サブストリングの2番目のパラメーターは排他的であるため、この回答はストリングを9文字にトリミングします。
emulcahy 2013

8

または、手元にStringUtilsがない場合は、このメソッドを使用できます。

public static String abbreviateString(String input, int maxLength) {
    if (input.length() <= maxLength) 
        return input;
    else 
        return input.substring(0, maxLength-2) + "..";
}

あなたのコードは私にとってはうまくいきませんでした。これを試してくださいSystem.out.println(abbreviateString("ABC\ud83d\udc3bDEF", 6));
T3rm1

4

文字列の最後の10文字をトリミングして保持する方法を探している場合に備えて。

s = s.substring(Math.max(s.length(),10) - 10);


1

tl; dr

切り捨てるとき、最後の場所に省略記号)文字を要求しているようです。これは、入力文字列を操作するためのワンライナーです。

String input = "abcdefghijkl";
String output = ( input.length () > 10 ) ? input.substring ( 0 , 10 - 1 ).concat ( "…" ) : input;

IdeOne.comでこのコードがライブで実行されることを確認してください。

abcdefghi…

三項演算子

三項演算子を使用して、ワンライナーを作成できます。

String input = "abcdefghijkl" ;

String output = 
    ( input.length() > 10 )          // If too long…
    ?                                
    input     
    .substring( 0 , 10 - 1 )         // Take just the first part, adjusting by 1 to replace that last character with an ellipsis.
    .concat( "…" )                   // Add the ellipsis character.
    :                                // Or, if not too long…
    input                            // Just return original string.
;

IdeOne.comでこのコードがライブで実行されることを確認してください。

abcdefghi…

Javaストリーム

Java 9以降では、Java Streams機能がこれを興味深いものにしています。興味深いですが、最善の方法ではないかもしれません。

値ではなくコードポイントを使用しcharます。charタイプは遺産である、とに限定されるのA部分集合可能なすべてのUnicode文字。

String input = "abcdefghijkl" ;
int limit = 10 ;
String output =
        input
                .codePoints()
                .limit( limit )
                .collect(                                    // Collect the results of processing each code point.
                        StringBuilder::new,                  // Supplier<R> supplier
                        StringBuilder::appendCodePoint,      // ObjIntConsumer<R> accumulator
                        StringBuilder::append                // BiConsumer<R,​R> combiner
                )
                .toString()
        ;

切り詰められた余分な文字がある場合は、最後の文字を省略記号に置き換え ます。

if ( input.length () > limit )
{
    output = output.substring ( 0 , output.length () - 1 ) + "…";
}

流線を「制限を超えている場合は省略」の部分と組み合わせる方法を考えることができたとしたら。


いいえ、明らかに、彼はストリングが11以上の長さに達した場合、ストリングの長さをトリムしたいと考えています。新しいAIシステム
oOに

1
@ JD333あなたのコメントは私をエスケープします。ここでは、省略記号を含めて長さを10に切り詰めることを示しています。
バジルブルク

0
str==null ? str : str.substring(0, Math.min(str.length(), 10))

または、

str==null ? "" : str.substring(0, Math.min(str.length(), 10))

nullで動作します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.