Führende und nachfolgende Zeichen aus einer Zeichenfolge entfernen

Entfernen Sie führende und nachfolgende Zeichen aus einer Zeichenfolge

1. Einführung

In diesem kurzen Tutorial sehen wir verschiedene Möglichkeiten, um führende und nachfolgende Zeichen ausString zu entfernen. Der Einfachheit halber werden in den Beispielen Nullen entfernt.

Mit jeder Implementierung erstellen wir zwei Methoden: eine für führende und eine für nachfolgende Nullen.

Dieses Problem hat einen Randfall: Was wollen wir tun, wenn die Eingabe nur Nullen enthält? Ein leeresString oder einString mit einer einzelnen Null zurückgeben? In jeder der Lösungen werden Implementierungen für beide Anwendungsfälle angezeigt.

Wir haben Unit-Tests für jede Implementierung, die Sie inon GitHub finden.

2. Verwenden vonStringBuilder

In unserer ersten Lösung erstellen wir von Anfang oder Ende einStringBuilder 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();
}

Beachten Sie, dass wirStringBuilder.setLength() anstelle vonStringBuilder.deleteCharAt() verwenden, wenn wir nachfolgende Nullen entfernen, da dadurch auch die letzten Zeichen gelöscht werden und die Leistung erhöht wird.

Wenn wirdon’t want to return an empty String, wenn die Eingabe nur Nullen enthält, müssen wir nurstop the loop if there’s only a single character left tun.

Deshalb ändern wir die Schleifenbedingung:

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. Verwenden vonString.subString()

Wenn wir in dieser Lösung führende oder nachfolgende Nullen entfernen, erhalten wirfind the position of the first or last non-zero character.

Danach müssen wir nur nochsubstring() aufrufen, um die restlichen Teile zurückzugeben:

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

Beachten Sie, dass wir die Variableindex vor der for-Schleife deklarieren müssen, da wir die Variable außerhalb des Gültigkeitsbereichs der Schleife verwenden möchten.

Beachten Sie auch, dass wir manuell nach Zeichen ungleich Null suchen müssen, daString.indexOf() undString.lastIndexOf() nur für eine genaue Übereinstimmung funktionieren.

Wenn wirdon’t want to return an empty String, müssen wir dasselbe tun wie zuvor: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. Verwenden von Apache Commons

Apache Commons hat viele nützliche Klassen, einschließlichorg.apache.commons.lang.StringUtils. Genauer gesagt ist diese Klasse in Apache Commons Lang3.

4.1. Abhängigkeiten

Wir könnenApache Commons Lang3 verwenden, indem wir diese Abhängigkeit in unserepom.xml-Datei einfügen:


    org.apache.commons
    commons-lang3
    3.8.1

4.2. Implementierung

In der KlasseStringUtils haben wir die MethodenstripStart() undstripEnd(). Sie entfernen führende und nachfolgende Zeichen.

Da es genau das ist, was wir brauchen, ist unsere Lösung ziemlich einfach:

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

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

Leider können wir nicht konfigurieren, ob wir alle Vorkommen entfernen möchten oder nicht. Daher müssen wir es manuell steuern.

Wenn die Eingabe nicht leer war, aber das gestrippteString leer ist, müssen wir genau eine Null zurückgeben:

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

Beachten Sie, dass diese MethodenString als zweiten Parameter akzeptieren. DiesesString repräsentiert eine Reihe von Zeichen, keine Sequenz, die wir entfernen möchten.

Wenn wir beispielsweise“01” übergeben, werden alle führenden oder nachfolgenden Zeichen entfernt, die entweder‘0' oder‘1' sind.

5. Mit Guave

Guava bietet auch viele Utility-Klassen. Für dieses Problem können wircom.google.common.base.CharMatcher verwenden, das Dienstprogrammmethoden für die Interaktion mit übereinstimmenden Zeichen bereitstellt.

5.1. Abhängigkeiten

Um Guava zu verwenden, sollten wir unsererpom.xml-Datei die folgendendependencies hinzufügen:


    com.google.guava
    guava
    27.0.1-jre

Beachten Sie, dass wir, wenn wir Guava in einer Android-Anwendung verwenden möchten, stattdessen die Version27.0-android verwenden sollten.

5.2. Implementierung

In unserem Fall sind wir antrimLeadingFrom() undtrimTrailingFrom() interessiert.

Wie der Name schon sagt, entfernen sie alle führenden bzw. nachfolgenden Zeichen ausString, die mitCharMatcher übereinstimmen:

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

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

Sie haben dieselben Eigenschaften wie die Apache-Commons-Methoden, die wir gesehen haben.

Wenn wir also nicht alle Nullen entfernen möchten, können wir denselben Trick verwenden:

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

Beachten Sie, dass wir mitCharMatcher komplexere Übereinstimmungsregeln erstellen können.

6. Reguläre Ausdrücke verwenden

Da unser Problem ein Mustervergleichsproblem ist, können wir reguläre Ausdrücke verwenden:we want to match all zeroes at the beginning or the end vonString.

Darüber hinaus möchten wir diese übereinstimmenden Nullen entfernen. Mit anderen Worten, wir wollenreplace them with nothing, or in other words, an empty String.

Genau das können wir mit der MethodeString.replaceAll()tun:

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

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

Wenn wir nicht alle Nullen entfernen möchten, können wir dieselbe Lösung verwenden, die wir für Apache Commons und Guava verwendet haben. Es gibt jedoch einen reinen regulären Ausdruck, um dies zu tun: Wir müssen ein Muster bereitstellen, das nicht mit den gesamtenString übereinstimmt.

Wenn die Eingabe nur Nullen enthält, verhindert die Regexp-Engine auf diese Weise, dass genau eine übereinstimmt. Wir können dies mit den folgenden Mustern tun:

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

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

Beachten Sie, dass“(?!^)” und“(?!$)” bedeuten, dass es nicht der Anfang oder das Ende vonString ist.

7. Fazit

In diesem Tutorial haben wir verschiedene Möglichkeiten gesehen, führende und nachfolgende Zeichen ausString zu entfernen. Die Wahl zwischen diesen Implementierungen ist oft einfach eine persönliche Präferenz.

Wie üblich sind die Beispiele inover on GitHub verfügbar.