1. 개요

String.trim () 메서드 는 후행 및 선행 공백을 제거합니다. 그러나 L-Trim 또는 R-Trim을 수행하는 것에 대한 지원은 없습니다.

이 사용방법(예제)에서는이를 구현할 수있는 몇 가지 방법을 살펴 보겠습니다. 결국 우리는 그들의 성능을 비교할 것입니다.

2. while 루프

가장 간단한 해결책은 몇 개의 while 루프를 사용하여 문자열을 살펴 보는 것 입니다.

L-Trim의 경우 공백이 아닌 문자가 나올 때까지 왼쪽에서 오른쪽으로 문자열을 읽습니다.

int i = 0;
while (i < s.length() && Character.isWhitespace(s.charAt(i))) {
    i++;
}
String ltrim = s.substring(i);

그러면 ltrim 은 공백이 아닌 첫 번째 문자에서 시작하는 하위 문자열입니다.

또는 R-Trim의 경우 공백이 아닌 문자가 나올 때까지 오른쪽에서 왼쪽으로 문자열을 읽습니다.

int i = s.length()-1;
while (i >= 0 && Character.isWhitespace(s.charAt(i))) {
    i--;
}
String rtrim = s.substring(0,i+1);

rtrim 은 시작 부분에서 시작하여 공백이 아닌 첫 번째 문자에서 끝나는 부분 문자열입니다.

3. 정규 표현식을 사용한 String.replaceAll

또 다른 옵션은 String.replaceAll () 및 정규식을 사용하는 것입니다.

String ltrim = src.replaceAll("^\\s+", "");
String rtrim = src.replaceAll("\\s+$", "");

(\\ s +)는 하나 이상의 공백 문자와 일치하는 정규식입니다. 정규식의 시작과 끝에있는 캐럿 (^) 및 ($)는 행의 시작과 끝을 일치시킵니다.

4. Pattern.compile ().matcher ()

java.util.regex.Pattern 과 함께 정규식을 재사용 할 수도 있습니다.

private static Pattern LTRIM = Pattern.compile("^\\s+");
private static Pattern RTRIM = Pattern.compile("\\s+$");

String ltrim = LTRIM.matcher(s).replaceAll("");
String rtim = RTRIM.matcher(s).replaceAll("");

5. 아파치 커먼즈

또한 Apache Commons StringUtils # stripStart#stripEnd 메서드를 사용하여 공백을 제거 할 수 있습니다.

그 들어, 먼저 추가 할 수 공유지 - lang3의  의존성을 :

<dependency> 
    <groupId>org.apache.commons</groupId> 
    <artifactId>commons-lang3</artifactId> 
    <version>3.11</version> 
</dependency>

문서에 따라 공백을 제거하기 위해 null사용 합니다.

String ltrim = StringUtils.stripStart(src, null);
String rtrim = StringUtils.stripEnd(src, null);

6. 구아바

마지막으로 Guava CharMatcher # trimLeadingFrom#trimTrailingFrom  메서드를 활용하여 동일한 결과를 얻습니다.

다시 한 번 적절한 Maven 의존성을 추가해 보겠습니다. 이번에는 guava입니다 .

<dependency> 
    <groupId>com.google.guava</groupId> 
    <artifactId>guava</artifactId> 
    <version>28.2-jre</version> 
</dependency>

그리고 Guava에서는 Apache Commons에서 수행하는 방법과 매우 유사하며보다 구체적인 방법을 사용합니다.

String ltrim = CharMatcher.whitespace().trimLeadingFrom(s); 
String rtrim = CharMatcher.whitespace().trimTrailingFrom(s);

7. 성능 비교

메서드의 성능을 살펴 보겠습니다. 평소와 같이 오픈 소스 프레임 워크 JMH ( Java Microbenchmark Harness )를 사용하여 나노초 단위로 다른 대안을 비교합니다.

7.1. 벤치 마크 설정

벤치 마크의 초기 구성을 위해 5 개의 포크와 평균 시간 계산 시간 (나노초)을 사용했습니다.

@Fork(5)
@State(Scope.Benchmark)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)

설정 방법에서 원본 메시지 필드와 비교할 결과 문자열을 초기화합니다.

@Setup
public void setup() {
    src = "       White spaces left and right          ";
    ltrimResult = "White spaces left and right          ";
    rtrimResult = "       White spaces left and right";
}

모든 벤치 마크는 먼저 왼쪽 공백을 제거한 다음 오른쪽 공백을 제거한 다음 마지막으로 결과를 예상 문자열과 비교합니다.

7.2. while 루프

첫 번째 벤치 마크로 while 루프 접근 방식을 사용하겠습니다 .

@Benchmark
public boolean whileCharacters() {
    String ltrim = whileLtrim(src);
    String rtrim = whileRtrim(src);
    return checkStrings(ltrim, rtrim);
}

7.3. String.replaceAll ()  정규 표현식

그런 다음 String.replaceAll ()을 시도해 보겠습니다 .

@Benchmark
public boolean replaceAllRegularExpression() {
    String ltrim = src.replaceAll("^\\s+", "");
    String rtrim = src.replaceAll("\\s+$", "");
    return checkStrings(ltrim, rtrim);
}

7.4. Pattern.compile (). matches ()

그 후 Pattern.compile (). matches () :

@Benchmark
public boolean patternMatchesLTtrimRTrim() {
    String ltrim = patternLtrim(src);
    String rtrim = patternRtrim(src);
    return checkStrings(ltrim, rtrim);
}

7.5. Apache Commons

넷째, Apache Commons :

@Benchmark
public boolean apacheCommonsStringUtils() {
    String ltrim = StringUtils.stripStart(src, " ");
    String rtrim = StringUtils.stripEnd(src, " ");
    return checkStrings(ltrim, rtrim);
}

7.6. 구아바

마지막으로 Guava를 사용하겠습니다.

@Benchmark
public boolean guavaCharMatcher() {
    String ltrim = CharMatcher.whitespace().trimLeadingFrom(src);
    String rtrim = CharMatcher.whitespace().trimTrailingFrom(src);
    return checkStrings(ltrim, rtrim);
}

7.7. 결과 분석

그리고 다음과 유사한 결과를 얻을 수 있습니다.

# Run complete. Total time: 00:16:57

Benchmark                               Mode  Cnt     Score    Error  Units
LTrimRTrim.apacheCommonsStringUtils     avgt  100   108,718 ±  4,503  ns/op
LTrimRTrim.guavaCharMatcher             avgt  100   113,601 ±  5,563  ns/op
LTrimRTrim.patternMatchesLTtrimRTrim    avgt  100   850,085 ± 17,578  ns/op
LTrimRTrim.replaceAllRegularExpression  avgt  100  1046,660 ±  7,151  ns/op
LTrimRTrim.whileCharacters              avgt  100   110,379 ±  1,032  ns/op

그리고 우리의 승자는 while 루프, Apache Commons 및 Guava 인 것 같습니다!

8. 결론

이 예제에서 우리는 String 시작과 끝에서 공백 문자를 제거하는 몇 가지 다른 방법을 살펴 보았습니다 .

이 결과를 얻기 위해 while 루프, String.replaceAll (),  Pattern.matcher (). replaceAll (), Apache Commons 및 Guava를 사용했습니다.

항상 그렇듯이 코드는 GitHub에서 사용할 수 있습니다 .