1. 概述

本文将深入探讨 String 类中的各种 strip 方法。我们将通过实际示例展示它们的用法,并分析不同场景下的适用性。最后,我们将这些方法与 String 类的经典 trim() 方法进行对比分析。

为便于演示,我们使用以下字符串作为示例:

String s = " Baeldung ";

注意该字符串开头和结尾的空白字符。

2. Strip 方法详解

Java 11 引入了 strip()stripLeading()stripTrailing() 方法,Java 13 又补充了 stripIndent() 方法。这些方法的共同点是:它们都使用相同的空白字符定义——当字符的 Unicode 码点通过 Character.isWhitespace() 判断为 true 时,该字符被视为空白字符。

2.1. strip() 方法

当需要同时去除字符串首尾空白时,strip() 是最佳选择:

@Test
void givenString_whenUsingStripMethod_thenRemoveTrailingLeadingWhitespace() {
    assertThat(s.strip())
      .doesNotStartWith(" ")
      .doesNotEndWith(" ")
      .isEqualTo("Baeldung");
}

处理结果将返回全新的 "Baeldung" 字符串。这里强调"全新"是因为 String 的不可变性——所有操作都会创建新对象而非修改原对象。

⚠️ 特殊情况:若字符串仅包含空白字符,strip() 将返回空字符串:

@Test
void givenWhitespaceString_whenUsingStripMethod_thenObtainEmptyString() {
    assertThat(" ".strip()).isEmpty();
}

2.2. stripLeading() 方法

当只需要去除开头空白时,使用 stripLeading()

@Test
void givenString_whenUsingStripLeadingMethod_thenRemoveLeadingWhitespace() {
    assertThat(s.stripLeading())
      .doesNotStartWith(" ")
      .endsWith(" ")
      .isEqualTo("Baeldung ");
}

注意测试断言中字符串尾部仍保留空白字符。

同样,纯空白字符串处理将返回空字符串:

@Test
void givenWhitespaceString_whenUsingStripLeadingMethod_thenObtainEmptyString() {
    assertThat(" ".stripLeading()).isEmpty();
}

2.3. stripTrailing() 方法

stripLeading() 相反,stripTrailing() 专门处理尾部空白:

@Test
void givenString_whenUsingStripTrailingMethod_thenRemoveTrailingWhitespace() {
    assertThat(s.stripTrailing())
      .startsWith(" ")
      .doesNotEndWith(" ")
      .isEqualTo(" Baeldung");
}

此时字符串开头的空白字符被保留。

纯空白字符串处理规则一致:

@Test
void givenWhitespaceString_whenUsingStripTrailingMethod_thenObtainEmptyString() {
    assertThat(" ".stripTrailing()).isEmpty();
}

2.4. stripIndent() 方法

Java 15 引入的文本块(Text Blocks)支持多行字符串定义。考虑以下文本块:

String textBlock = """
                B
                 a
                  e
                   l
                    d
                     u
                      n
                       g""";

**stripIndent() 方法用于移除每行的"偶然空白"**——本例中即首字母 B 前的所有空白。后续每行的额外空格被视为有意缩进,处理后相对位置保持不变:

@Test
void givenTextBlockWithExtraSpaceForEachNewLine_whenUsingStripIndent_thenIndentTextBlock() {
    String textBlock = """
            B
             a
              e
               l
                d
                 u
                  n
                   g""";
    assertThat(textBlock.stripIndent())
      .isEqualTo("B\n a\n  e\n   l\n    d\n     u\n      n\n       g");
}

结果中首行无空白,其他行保留相对缩进。

再看一个更直观的缩进保持示例:

@Test
void givenTextBlockWithFourthLineAsLeftMost_whenUsingStripIndent_thenIndentTextBlock() {
        String textBlock = """
             B
              a
               e
            l
                 d
                  u
                   n
                    g""";
    assertThat(textBlock.stripIndent())
      .isEqualTo(" B\n  a\n   e\nl\n     d\n      u\n       n\n        g");
}

stripIndent() 将含 l 的行完全左对齐,其他行保持相对缩进关系。

3. Strip 方法 vs trim() 方法对比

String 类中还有一个经典空白处理方法 trim()。关键区别在于:两者对空白字符的定义不同。尽管 strip()trim() 都处理首尾空白,但具体行为存在差异。

3.1. trim() 方法

如前所述,strip 方法通过 Character.isWhitespace() 判断空白。而 trim() 将码点在 U+0000(空字符)到 U+0020(空格)之间的字符都视为空白

验证包含 U+0000 的字符串:

@Test
void givenStringWithUnicodeForNull_whenUsingTrimMethod_thenRemoveUnicodeForNull() {
    assertThat("Baeldung\u0000".trim()).isEqualTo("Baeldung");
}

空字符被 trim() 视为空白并移除。

再看超出 trim() 范围的字符(如 U+0021 感叹号):

@Test
void givenStringWithUnicodeForExclamationMark_whenUsingTrimMethod_thenObtainOriginalStringValue() {
    assertThat("Baeldung\u0021".trim()).isEqualTo("Baeldung!");
}

感叹号被完整保留,Unicode 码点与字符可互换使用。

3.2. strip() vs trim() 方法差异

通过以下对比案例可清晰看出差异:

@Test
void givenStringWithUnicodeForNull_whenUsingStripMethod_thenObtainOriginalStringValue() {     
    assertThat("Baeldung\u0000".strip()).isEqualTo("Baeldung\u0000");
}

关键差异strip() 保留了空字符(U+0000),因为根据 Character.isWhitespace() 定义,它不被视为空白字符。

4. 总结

本文全面解析了 String 类中的 strip 方法族,并通过示例展示了它们的适用场景。我们重点揭示了 strip 方法与 trim() 方法在空白字符定义上的本质差异,帮助开发者在不同场景下做出正确选择。

文中的所有代码示例可在 GitHub 仓库 获取。


原始标题:Java Strip Methods | Baeldung