Rimuovi i caratteri iniziali e finali da una stringa

1. Introduzione

In questo breve tutorial, vedremo diversi modi per rimuovere i caratteri iniziali e finali da una stringa . Per semplicità, rimuoveremo gli zeri negli esempi.

Con ogni implementazione creeremo due metodi: uno per gli zeri iniziali e uno per gli zeri finali.

Questo problema ha un caso limite: cosa vogliamo fare, quando l'ingresso contiene solo zeri? Restituire una stringa vuota o una stringa contenente un singolo zero? Vedremo implementazioni per entrambi i casi d'uso in ciascuna delle soluzioni.

Abbiamo unit test per ogni implementazione, che puoi trovare su GitHub.

2. Utilizzo di StringBuilder

Nella nostra prima soluzione, creeremo uno StringBuilder con la stringa originale e cancelleremo i caratteri non necessari dall'inizio o dalla fine:

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

Nota che usiamo StringBuilder.setLength () invece di StringBuilder.deleteCharAt () quando rimuoviamo gli zeri finali perché elimina anche gli ultimi pochi caratteri ed è più performante.

Se non vogliamo restituire una stringa vuota quando l'input contiene solo zeri, l'unica cosa che dobbiamo fare è interrompere il ciclo se rimane un solo carattere .

Pertanto, cambiamo la condizione del ciclo:

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. Utilizzo di String.subString ()

In questa soluzione, quando rimuoviamo gli zeri iniziali o finali, troviamo la posizione del primo o dell'ultimo carattere diverso da zero.

Dopodiché, dobbiamo solo chiamare substring () , per restituire le parti rimanenti:

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

Nota che dobbiamo dichiarare l' indice della variabile prima del ciclo for perché vogliamo usare la variabile al di fuori dell'ambito del ciclo.

Si noti inoltre che dobbiamo cercare manualmente caratteri diversi da zero, poiché String.indexOf () e String.lastIndexOf () funzionano solo per la corrispondenza esatta.

Se non vogliamo restituire una stringa vuota , dobbiamo fare la stessa cosa di prima: cambiare la condizione del ciclo :

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. Utilizzo di Apache Commons

Apache Commons ha molte classi utili, tra cui org.apache.commons.lang.StringUtils . Per essere più precisi, questa classe è in Apache Commons Lang3.

4.1. Dipendenze

Possiamo usare Apache Commons Lang3 inserendo questa dipendenza nel nostro file pom.xml :

 org.apache.commons commons-lang3 3.8.1 

4.2. Implementazione

Nella classe StringUtils , abbiamo i metodi stripStart () e stripEnd () . Rimuovono rispettivamente i caratteri iniziali e finali.

Poiché è esattamente ciò di cui abbiamo bisogno, la nostra soluzione è piuttosto semplice:

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

Sfortunatamente, non possiamo configurare, se vogliamo rimuovere tutte le occorrenze o meno. Pertanto, dobbiamo controllarlo manualmente.

Se l'input non era vuoto, ma la Stringa spogliata è vuota, allora dobbiamo restituire esattamente uno zero:

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

Nota che questi metodi accettano una stringa come secondo parametro. Questa stringa rappresenta un insieme di caratteri, non una sequenza che vogliamo rimuovere.

Ad esempio, se passiamo "01" , rimuoveranno tutti i caratteri iniziali o finali, che sono "0" o "1" .

5. Utilizzando Guava

Guava fornisce anche molte classi di utilità. Per questo problema, possiamo utilizzare com.google.common.base.CharMatcher , che fornisce metodi di utilità per interagire con i caratteri corrispondenti.

5.1. Dipendenze

Per utilizzare Guava, dovremmo aggiungere le seguenti dipendenze al nostro file pom.xml :

 com.google.guava guava 27.0.1-jre 

Nota che se vogliamo usare Guava in un'applicazione Android, dovremmo usare invece la versione 27.0-android .

5.2. Implementazione

Nel nostro caso, siamo interessati a trimLeadingFrom () e trimTrailingFrom () .

Come suggerisce il nome, rimuovono rispettivamente qualsiasi carattere iniziale o finale da una stringa , che corrisponde a CharMatcher :

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

Hanno le stesse caratteristiche dei metodi Apache Commons che abbiamo visto.

Pertanto, se non vogliamo rimuovere tutti gli zeri, possiamo usare lo stesso trucco:

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

Nota che con CharMatcher possiamo creare regole di corrispondenza più complesse.

6. Using Regular Expressions

Since our problem is a pattern matching problem, we can use regular expressions: we want to match all zeroes at the beginning or the end of a String.

On top of that, we want to remove those matching zeroes. In other words, we want to replace them with nothing, or in other words, an empty String.

We can do exactly that, with the String.replaceAll() method:

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

If we don't want to remove all zeroes, we could use the same solution we used with Apache Commons and Guava. However, there's a pure regular expression way to do this: we have to provide a pattern, which doesn't match the whole String.

In questo modo, se l'input contiene solo zeri, il motore delle espressioni regolari ne manterrà esattamente uno fuori dalla corrispondenza. Possiamo farlo con i seguenti schemi:

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

Nota che "(?! ^)" E "(?! $)" Significa che non è rispettivamente l'inizio o la fine della stringa .

7. Conclusione

In questo tutorial, abbiamo visto diversi modi per rimuovere i caratteri iniziali e finali da una stringa . La scelta tra queste implementazioni è spesso semplicemente una preferenza personale.

Come al solito, gli esempi sono disponibili su GitHub.