Entfernen Sie führende und nachfolgende Zeichen aus einer Zeichenfolge

1. Einleitung

In diesem kurzen Tutorial sehen wir verschiedene Möglichkeiten, um führende und nachfolgende Zeichen aus einem String 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 möchten wir tun, wenn die Eingabe nur Nullen enthält? Eine leere Zeichenfolge oder eine Zeichenfolge mit einer einzelnen Null zurückgeben? Wir werden Implementierungen für beide Anwendungsfälle in jeder der Lösungen sehen.

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

2. Verwenden von StringBuilder

In unserer ersten Lösung erstellen wir einen StringBuilder mit dem ursprünglichen String und löschen die unnötigen Zeichen am Anfang oder am Ende:

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 wir StringBuilder.setLength () anstelle von StringBuilder.deleteCharAt () verwenden, wenn wir nachfolgende Nullen entfernen, da dadurch auch die letzten Zeichen gelöscht werden und die Leistung erhöht wird.

Wenn wir keinen leeren String zurückgeben möchten, wenn die Eingabe nur Nullen enthält, müssen wir die Schleife nur stoppen, wenn nur noch ein einziges Zeichen übrig ist .

Daher ä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 von String.subString ()

Wenn wir in dieser Lösung führende oder nachfolgende Nullen entfernen, finden wir die Position des ersten oder letzten Zeichens ungleich Null.

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

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

Beachten Sie , dass wir die Variable deklarieren Index vor der for - Schleife , da wir die Variable außerhalb der Schleife des Oszilloskops verwendet werden soll.

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

Wenn wir keinen leeren String zurückgeben möchten , müssen wir dasselbe wie zuvor tun: Ändern Sie die Schleifenbedingung :

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

4. Verwenden von Apache Commons

Apache Commons verfügt über viele nützliche Klassen, einschließlich org.apache.commons.lang.StringUtils . Genauer gesagt befindet sich diese Klasse in Apache Commons Lang3.

4.1. Abhängigkeiten

Wir können Apache Commons Lang3 verwenden, indem wir diese Abhängigkeit in unsere Datei pom.xml einfügen :

 org.apache.commons commons-lang3 3.8.1 

4.2. Implementierung

In der StringUtils- Klasse haben wir die Methoden stripStart () und stripEnd () . 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 der gestrippte String 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 Methoden einen String als zweiten Parameter akzeptieren . Dieser String stellt einen Satz von Zeichen, nicht eine Folge wir entfernen möchten.

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

5. Verwenden von Guave

Guava bietet auch viele Dienstprogrammklassen. Für dieses Problem können wir com.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 unserer Datei pom.xml die folgenden Abhängigkeiten 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 Version 27.0-android verwenden sollten.

5.2. Implementierung

In unserem Fall interessieren wir uns für trimLeadingFrom () und trimTrailingFrom () .

Wie der Name schon sagt, entfernen sie alle führenden bzw. nachfolgenden Zeichen aus einem String , der dem CharMatcher entspricht :

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 mit CharMatcher komplexere Übereinstimmungsregeln erstellen können.

6. Verwenden regulärer Ausdrücke

Da unser Problem ein Pattern - Matching Problem ist, können wir reguläre Ausdrücke verwenden: wir alle Nullen am Anfang oder am Ende übereinstimmen sollen von einem String .

Darüber hinaus möchten wir diese übereinstimmenden Nullen entfernen. Mit anderen Worten, wir möchten sie durch nichts oder mit anderen Worten durch einen leeren String ersetzen .

Genau das können wir mit der String.replaceAll () -Methode 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 dem gesamten String übereinstimmt .

Auf diese Weise hält die Regexp-Engine genau eins von der Übereinstimmung fern, wenn die Eingabe nur Nullen enthält. 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 des Strings ist .

7. Fazit

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

Wie üblich sind die Beispiele auf GitHub verfügbar.