1.はじめに

この短いチュートリアルでは、

String

から前後の文字を削除する方法をいくつか紹介します。簡単にするために、例ではゼロを削除します。

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

この問題には最悪の場合があります。入力にゼロのみが含まれている場合に何をしたいですか。空の

String

、または単一のゼロを含む

String

を返しますか?どちらのソリューションにも、両方のユースケースの実装があります。

私たちはあなたがhttps://github.com/eugenp/tutorials/tree/master/java-strings[on GitHub]を見つけることができる各実装のための単体テストを持っています。

2.

StringBuilder

を使う

最初のソリューションでは、元の

String

を使用して


StringBuilder

を作成し、不要な文字

を先頭または末尾から削除します。

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

を使用します。

入力にゼロしか含まれていないときに空の

String

** を返したくない場合は、1文字だけ残っていればループを停止するだけです。

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

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

を使う

このソリューションでは、先頭または末尾のゼロを削除すると、最初または最後のゼロ以外の文字の位置がわかります。

その後、残りの部分を返すために

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

は完全一致の場合にのみ機能するため、ゼロ以外の文字を手動で探す必要があることにも注意してください。

空の

String


を返したくない場合は、以前と同じことをする必要があります。

ループ条件を変更する** :

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

ファイルに挿入することでhttps://search.maven.org/search?q=a:commons-lang3[Apache Commons Lang3]を使用できます。

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

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を使用するには、次のhttps://search.maven.org/search?q=a:guava[dependencies]を

pom.xml

ファイルに追加してください。

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

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.正規表現を使う

私たちの問題はパターンマッチングの問題なので、正規表現を使うことができます。

それに加えて、一致するゼロを削除します。言い換えれば、

それらを何もないもの、つまり空の

String


に置き換えたいのです。


String.replaceAll()

メソッドを使用して、これを正確に実行できます。

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

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

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

String

全体とは一致しません。

そのようにして、入力がゼロのみを含む場合、正規表現エンジンはマッチングから正確に1を除外します。次のパターンでこれを実行できます。

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

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


“(?!^)”



“(?!$)”

は、それぞれ

String

の始めまたは終わりではないことを意味します。

7.まとめ

このチュートリアルでは、

String

から先頭と末尾の文字を削除するいくつかの方法を説明しました。これらの実装間の選択は、しばしば単に個人的な好みです。

いつものように、例はhttps://github.com/eugenp/tutorials/tree/master/java-strings[GitHubで利用可能]にあります。