文字列から先頭と末尾の文字を削除する

文字列から先頭と末尾の文字を削除する

1. 前書き

この短いチュートリアルでは、Stringから先頭と末尾の文字を削除するいくつかの方法を説明します。 簡単にするために、例ではゼロを削除します。

実装ごとに、2つのメソッドを作成します。1つは先行ゼロ用、もう1つは後続ゼロ用です。

この問題にはエッジケースがあります:入力にゼロのみが含まれている場合、何をしたいのでしょうか? 空のString、または単一のゼロを含むStringを返しますか? 各ソリューションの両方のユースケースの実装を確認します。

実装ごとに単体テストがあり、on GitHubを見つけることができます。

2. StringBuilderの使用

最初のソリューションでは、最初または最後からStringBuilder with the original String, and we’ll delete the unnecessary charactersを作成します。

String removeLeadingZeroes(String s) {
    StringBuilder sb = new StringBuilder(s);
    while (sb.length() > 0 && sb.charAt(0) == '0') {
        sb.deleteCharAt(0);
    }
    return sb.toString();
}

String removeTrailingZeroes(String s) {
    StringBuilder sb = new StringBuilder(s);
    while (sb.length() > 0 && sb.charAt(sb.length() - 1) == '0') {
        sb.setLength(sb.length() - 1);
    }
    return sb.toString();
}

末尾のゼロを削除するときは、StringBuilder.deleteCharAt()の代わりにStringBuilder.setLength()を使用することに注意してください。これは、最後の数文字も削除され、パフォーマンスが向上するためです。

入力にゼロのみが含まれているときにdon’t want to return an empty Stringを実行する場合、実行する必要があるのはstop the loop if there’s only a single character leftだけです。

したがって、ループ条件を変更します。

String removeLeadingZeroes(String s) {
    StringBuilder sb = new StringBuilder(s);
    while (sb.length() > 1 && sb.charAt(0) == '0') {
        sb.deleteCharAt(0);
    }
    return sb.toString();
}

String removeTrailingZeroes(String s) {
    StringBuilder sb = new StringBuilder(s);
    while (sb.length() > 1 && sb.charAt(sb.length() - 1) == '0') {
        sb.setLength(sb.length() - 1);
    }
    return sb.toString();
}

3. String.subString()の使用

このソリューションでは、先頭または末尾のゼロを削除すると、find the position of the first or last non-zero character.

その後、残りの部分を返すために、substring()を呼び出すだけです。

String removeLeadingZeroes(String s) {
    int index;
    for (index = 0; index < s.length(); index++) {
        if (s.charAt(index) != '0') {
            break;
        }
    }
    return s.substring(index);
}

String removeTrailingZeroes(String s) {
    int index;
    for (index = s.length() - 1; index >= 0; index--) {
        if (s.charAt(index) != '0') {
            break;
        }
    }
    return s.substring(0, index + 1);
}

ループのスコープ外で変数を使用するため、forループの前に変数indexを宣言する必要があることに注意してください。

また、String.indexOf()String.lastIndexOf()は完全一致に対してのみ機能するため、ゼロ以外の文字を手動で検索する必要があることにも注意してください。

don’t want to return an empty Stringの場合、前と同じことを行う必要があります。change the loop condition

String removeLeadingZeroes(String s) {
    int index;
    for (index = 0; index < s.length() - 1; index++) {
        if (s.charAt(index) != '0') {
            break;
        }
    }
    return s.substring(index);
}

String removeTrailingZeroes(String s) {
    int index;
    for (index = s.length() - 1; index > 0; index--) {
        if (s.charAt(index) != '0') {
            break;
        }
    }
    return s.substring(0, index + 1);
}

4. Apache Commonsを使用する

Apache Commonsには、org.apache.commons.lang.StringUtilsを含む多くの便利なクラスがあります。 より正確には、このクラスはApache Commons Lang3にあります。

4.1. 依存関係

この依存関係をpom.xmlファイルに挿入することで、Apache Commons Lang3を使用できます。


    org.apache.commons
    commons-lang3
    3.8.1

4.2. 実装

StringUtilsクラスには、メソッドstripStart()stripEnd()があります。 それらはそれぞれ先頭と末尾の文字を削除します。

それがまさに私たちに必要なものなので、私たちのソリューションは非常に簡単です。

String removeLeadingZeroes(String s) {
    return StringUtils.stripStart(s, "0");
}

String removeTrailingZeroes(String s) {
    return StringUtils.stripEnd(s, "0");
}

残念ながら、すべてのオカレンスを削除するかどうかを設定することはできません。 したがって、手動で制御する必要があります。

入力が空ではなく、削除されたStringが空の場合、正確に1つのゼロを返す必要があります。

String removeLeadingZeroes(String s) {
    String stripped = StringUtils.stripStart(s, "0");
    if (stripped.isEmpty() && !s.isEmpty()) {
        return "0";
    }
    return stripped;
}

String removeTrailingZeroes(String s) {
    String stripped = StringUtils.stripEnd(s, "0");
    if (stripped.isEmpty() && !s.isEmpty()) {
        return "0";
    }
    return stripped;
}

これらのメソッドは、2番目のパラメーターとしてStringを受け入れることに注意してください。 このStringは、削除するシーケンスではなく、文字のセットを表します。

たとえば、“01”を渡すと、‘0'または‘1'の先頭または末尾の文字がすべて削除されます。

5. グアバの使用

Guavaは、多くのユーティリティクラスも提供します。 この問題には、com.google.common.base.CharMatcherを使用できます。これは、一致する文字と対話するためのユーティリティメソッドを提供します。

5.1. 依存関係

Guavaを使用するには、次のdependenciespom.xmlファイルに追加する必要があります。


    com.google.guava
    guava
    27.0.1-jre

AndroidアプリケーションでGuavaを使用する場合は、代わりにバージョン27.0-androidを使用する必要があることに注意してください。

5.2. 実装

この例では、trimLeadingFrom()trimTrailingFrom()に関心があります。

それらの名前が示すように、CharMatcherと一致するStringからそれぞれ先頭または末尾の文字を削除します。

String removeLeadingZeroes(String s) {
    return CharMatcher.is('0').trimLeadingFrom(s);
}

String removeTrailingZeroes(String s) {
    return CharMatcher.is('0').trimTrailingFrom(s);
}

これらは、私たちが見たApache Commonsのメソッドと同じ特性を持っています。

したがって、すべてのゼロを削除したくない場合は、同じトリックを使用できます。

String removeLeadingZeroes(String s) {
    String stripped = CharMatcher.is('0').trimLeadingFrom(s);
    if (stripped.isEmpty() && !s.isEmpty()) {
        return "0";
    }
    return stripped;
}

String removeTrailingZeroes(String s) {
    String stripped = CharMatcher.is('0').trimTrailingFrom(s);
    if (stripped.isEmpty() && !s.isEmpty()) {
        return "0";
    }
    return stripped;
}

CharMatcherを使用すると、より複雑なマッチングルールを作成できることに注意してください。

6. 正規表現を使用する

私たちの問題はパターンマッチングの問題であるため、正規表現を使用できます:Stringwe want to match all zeroes at the beginning or the end

さらに、一致するゼロを削除する必要があります。 つまり、replace them with nothing, or in other words, an empty Stringにします。

String.replaceAll()メソッドを使用すると、まさにそれを実行できます。

String removeLeadingZeroes(String s) {
    return s.replaceAll("^0+", "");
}

String removeTrailingZeroes(String s) {
    return s.replaceAll("0+$", "");
}

すべてのゼロを削除したくない場合は、ApacheCommonsとGuavaで使用したのと同じソリューションを使用できます。 ただし、これを行うための純粋な正規表現の方法があります。String全体と一致しないパターンを提供する必要があります。

このように、入力にゼロのみが含まれている場合、正規表現エンジンは一致から1つだけを除外します。 次のパターンでこれを行うことができます。

String removeLeadingZeroes(String s) {
    return s.replaceAll("^0+(?!$)", "");
}

String removeTrailingZeroes(String s) {
    return s.replaceAll("(?!^)0+$", "");
}

“(?!^)”“(?!$)”は、それぞれStringの始まりでも終わりでもないことを意味することに注意してください。

7. 結論

このチュートリアルでは、Stringから先頭と末尾の文字を削除するいくつかの方法を見ました。 これらの実装の選択は、多くの場合、単に個人的な好みです。

いつものように、例は利用可能なover on GitHubです。