문자열 길이를 기준으로 문자열 자르기


답변:


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

Math.min이와 같이 사용 하면 문자열이 이미보다 짧은 경우 예외가 발생하지 않습니다 10.


노트:

  1. 위의 실제 트리밍을 수행합니다. 마지막 세 문자 (!)를 잘 리면 점으로 바꾸려면 Apache Commons를 사용하십시오 StringUtils.abbreviate.

  2. 문자열에 BMP 외부의 유니 코드 코드 포인트가 포함되어 있으면 1 이 잘못 작동 할 수 있습니다 . 예를 들어 이모티콘. 모든 유니 코드 코드 포인트에 대해 올바르게 작동하는 (더 복잡한) 솔루션은 @ sibnick 's solution을 참조하십시오 .


1-평면 0에없는 유니 코드 코드 포인트 (BMP)는에서 "대리 쌍"(즉, 두 char값)으로 표시 String됩니다. 이것을 무시함으로써, 우리는 10 개 미만의 코드 포인트로 트리밍하거나, 대리 쌍의 중간에서 (나쁘게) 잘릴 수 있습니다. 반면에 String.length()더 이상 유니 코드 텍스트 길이의 이상적인 측정 값이 아니므로이를 기반으로 트리밍하는 것이 잘못되었을 수 있습니다.


Math.min 대신 조건부 검사를 수행 할 수 없으며 string이 max 인 경우에만 하위 문자열을 수행 할 수 있습니까? 예 :s = (s.length() > 10) ? s.substring(0,10) : s ;
rram

1
예, 물론 가능합니다. 문제를 해결하는 다른 방법은 다른 답변을 읽으십시오!
Stephen 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의 질문에 "줄임표"는 묻지 않습니다.
Stephen C

9
@StephenC-질문은 길이 제한이 10으로 주어지면 8 자 뒤에 2 개의 점이 표시됩니다. 이는 길이 줄임표와 비슷합니다 (3이 아닌 2 개의 점). 또한이 질문을 찾는 많은 사람들이 줄임표가 유용하다고 생각할 것입니다.
ToolmakerSteve

12
... 줄임표를 원하지 않으면 StringUtils.left ()가 도움이 될 수 있습니다.
Superole

1
참고로 HORIZONTAL ELLIPSIS 는 3 개의 FULL STOP 문자가 아닌 단일 문자입니다.…
Basil Bourque

53

StringUtils이를 수행 하는 Apache Commons 기능이 있습니다.

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. 왼쪽 JavaDocs

예의 : Steeve McCauley


22

평소처럼 아무도 UTF-16 대리 쌍을 신경 쓰지 않습니다. 그들에 대해보십시오 : 실제로 사용되는 가장 일반적인 비 BMP 유니 코드 문자는 무엇입니까? 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/browse/LANG-1343
Ryan Quinn

10

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


16
하위 문자열의 두 번째 매개 변수는 배타적이므로이 답변은 문자열을 9 자로 자릅니다.
emulcahy

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

3

Kotlin을 사용하면 다음과 같이 간단합니다.

yourString.take(10)

이 문자열에서 처음 n자를 포함하는 문자열을 반환하거나이 문자열이 더 짧은 경우 전체 문자열을 반환합니다.

선적 서류 비치


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 Streams 기능은 Java 9 이상에서이 기능을 흥미롭게 만듭니다. 흥미롭지 만 최선의 방법은 아닙니다.

우리는 값 보다는 코드 포인트를 사용 char합니다. 이 char유형은 레거시이며 가능한 모든 유니 코드 문자 의 하위 집합으로 제한됩니다 .

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 작업을해야합니다
JD333

1
@ JD333 당신의 의견은 저를 피합니다. 생략 부호를 포함하여 길이가 10으로 자르는 것이 바로 여기에 나와 있습니다.
Basil Bourque

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.