Java >> Java tutorial >  >> Tag >> char

Fjern ledende og efterfølgende tegn fra en streng

1. Introduktion

I dette korte selvstudie vil vi se flere måder at fjerne førende og efterfølgende tegn fra en streng . For nemheds skyld fjerner vi nuller i eksemplerne.

Med hver implementering vil vi skabe to metoder:en til at føre og en til at afslutte nuller.

Dette problem har en kantsag:hvad vil vi gøre, når input kun indeholder nuller? Returner en tom streng eller en streng indeholder et enkelt nul? Vi vil se implementeringer for begge use cases i hver af løsningerne.

Vi har enhedstests for hver implementering, som du kan finde på GitHub.

2. Brug af StringBuilder

I vores første løsning opretter vi en StringBuilder med den originale streng , og vi sletter de unødvendige tegn fra begyndelsen eller slutningen:

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

Bemærk, at vi bruger StringBuilder.setLength() i stedet for StringBuilder.deleteCharAt() når vi fjerner efterfølgende nuller, fordi det også sletter de sidste par tegn, og det er mere effektivt.

Hvis vi ikke ønsker at returnere en tom streng når input kun indeholder nuller, er det eneste, vi skal gøre, at stoppe løkken, hvis der kun er et enkelt tegn tilbage .

Derfor ændrer vi sløjfebetingelsen:

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. Brug af String.subString()

I denne løsning, når vi fjerner indledende eller efterfølgende nuller, finder vi positionen for det første eller sidste ikke-nul-tegn.

Derefter skal vi kun kalde substring() , for at returnere de resterende dele:

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

Bemærk, at vi er nødt til at erklære variablen indeks før for-løkken, fordi vi ønsker at bruge variablen uden for løkkens omfang.

Bemærk også, at vi skal lede efter tegn, der ikke er nul manuelt, da String.indexOf() og String.lastIndexOf() virker kun for nøjagtig matchning.

Hvis vi ikke ønsker at returnere en tom streng , vi skal gøre det samme som før:ændre sløjfebetingelsen :

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. Brug af Apache Commons

Apache Commons har mange nyttige klasser, herunder org.apache.commons.lang.StringUtils . For at være mere præcis er denne klasse i Apache Commons Lang3.

4.1. Afhængigheder

Vi kan bruge Apache Commons Lang3 ved at indsætte denne afhængighed i vores pom.xml fil:

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

4.2. Implementering

I StringUtils klasse, har vi metoderne stripStart() og stripEnd() . De fjerner henholdsvis førende og efterfølgende karakterer.

Da det er præcis, hvad vi har brug for, er vores løsning ret ligetil:

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

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

Desværre kan vi ikke konfigurere, om vi vil fjerne alle forekomster eller ej. Derfor skal vi styre det manuelt.

Hvis input ikke var tomt, men den strippede String er tom, så skal vi returnere præcis ét nul:

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

Bemærk, at disse metoder accepterer en streng som deres anden parameter. Denne streng repræsenterer et sæt tegn, ikke en sekvens, vi ønsker at fjerne.

For eksempel, hvis vi passerer "01" , vil de fjerne alle indledende eller efterfølgende tegn, som enten er '0' eller '1' .

5. Brug af Guava

Guava tilbyder også mange hjælpeklasser. Til dette problem kan vi bruge com.google.common.base.CharMatcher , som giver hjælpemetoder til at interagere med matchende tegn.

5.1. Afhængigheder

For at bruge Guava bør vi tilføje følgende afhængigheder til vores pom.xml fil:

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

Bemærk, at hvis vi vil bruge Guava i en Android-applikation, skal vi bruge version 27.0-android i stedet.

5.2. Implementering

I vores tilfælde er vi interesserede i trimLeadingFrom() og trimTrailingFrom() .

Som deres navn antyder, fjerner de ethvert for- og eftertegn fra en streng , som matcher CharMatcher :

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

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

De har de samme egenskaber, som Apache Commons-metoderne vi så.

Derfor, hvis vi ikke vil fjerne alle nuller, kan vi bruge det samme trick:

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

Bemærk, det med CharMatcher vi kan skabe mere komplekse matchningsregler.

6. Brug af regulære udtryk

Da vores problem er et mønstermatchningsproblem, kan vi bruge regulære udtryk:vi vil matche alle nuller i begyndelsen eller slutningen af en streng .

Oven i det ønsker vi at fjerne de matchende nuller. Med andre ord, vi ønsker at erstatte dem med ingenting, eller med andre ord, en tom streng .

Vi kan gøre præcis det med String.replaceAll() metode:

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

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

Hvis vi ikke vil fjerne alle nuller, kunne vi bruge den samme løsning, som vi brugte med Apache Commons og Guava. Der er dog en ren regulært udtryksmåde at gøre dette på:Vi skal levere et mønster, som ikke matcher hele strengen .

På den måde, hvis input kun indeholder nuller, vil regexp-motoren holde præcis én ude fra matchningen. Vi kan gøre dette med følgende mønstre:

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

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

Bemærk, at “(?!^)” og “(?!$)” betyder, at det ikke er begyndelsen eller slutningen af ​​strengen hhv.

7. Konklusion

I dette selvstudie så vi flere måder at fjerne førende og efterfølgende tegn fra en streng . Valget mellem disse implementeringer er ofte blot personlig præference.

Som sædvanlig er eksemplerne tilgængelige på GitHub.


Java tag