Fjern ledende og efterfølgende tegn fra en streng

1. Introduktion

I denne korte vejledning ser vi flere måder at fjerne ledende og efterfølgende tegn fra a Snor. Af hensyn til enkelheden fjerner vi nuller i eksemplerne.

Med hver implementering opretter vi to metoder: en til at lede og en til at følge nuller.

Dette problem har en kantstilstand: hvad vil vi gøre, når input kun indeholder nuller? Returner en tom Snor, eller a Snor indeholder et enkelt nul? Vi ser implementeringer for begge brugssager i hver af løsningerne.

Vi har enhedstest til hver implementering, som du kan finde på GitHub.

2. Brug StringBuilder

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

String removeLeadingZeroes (String s) {StringBuilder sb = nye StringBuilder (s); mens (sb.length ()> 0 && sb.charAt (0) == '0') {sb.deleteCharAt (0); } returner sb.toString (); } String removeTrailingZeroes (String s) {StringBuilder sb = nye StringBuilder (s); mens (sb.length ()> 0 && sb.charAt (sb.length () - 1) == '0') {sb.setLength (sb.length () - 1); } returner 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 performant.

Hvis vi ikke ønsker at returnere en tom Snor når input kun indeholder nuller, er det eneste, vi skal gøre, at stop sløjfen, hvis der kun er et enkelt tegn tilbage.

Derfor ændrer vi looptilstanden:

String removeLeadingZeroes (String s) {StringBuilder sb = nye StringBuilder (s); mens (sb.length ()> 1 && sb.charAt (0) == '0') {sb.deleteCharAt (0); } returner sb.toString (); } String removeTrailingZeroes (String s) {StringBuilder sb = nye StringBuilder (s); mens (sb.length ()> 1 && sb.charAt (sb.length () - 1) == '0') {sb.setLength (sb.length () - 1); } returner sb.toString (); }

3. Brug String.subString ()

I denne løsning, når vi fjerner ledende eller bageste nuller, vi find placeringen af ​​det første eller sidste tegn, der ikke er nul.

Derefter skal vi kun ringe understreng (), for at returnere de resterende dele:

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

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

Bemærk også, at vi er nødt til at kigge efter tegn, der ikke er nul manuelt, siden String.indexOf () og String.lastIndexOf () arbejde kun for nøjagtig matchning.

Hvis vi ikke ønsker at returnere en tom Snor, vi er nødt til at gøre det samme som før: ændre loop-tilstanden:

String removeLeadingZeroes (String s) {int-indeks; for (index = 0; index 0; index--) {if (s.charAt (index)! = '0') {break; }} returner s.substring (0, indeks + 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:

 org.apache.commons commons-lang3 3.8.1 

4.2. Implementering

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

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, hvis vi vil fjerne alle forekomster eller ej. Derfor er vi nødt til at kontrollere det manuelt.

Hvis input ikke var tom, men strippet Snor er tom, så skal vi returnere nøjagtigt et nul:

String removeLeadingZeroes (String s) {String stripped = StringUtils.stripStart (s, "0"); hvis (stripped.isEmpty () &&! s.isEmpty ()) {return "0"; } returneret strippet; } String removeTrailingZeroes (String s) {String stripped = StringUtils.stripEnd (s, "0"); hvis (stripped.isEmpty () &&! s.isEmpty ()) {return "0"; } returneret strippet; }

Bemærk, at disse metoder accepterer en Snor som deres anden parameter. Det her Snor repræsenterer et sæt tegn, ikke en rækkefølge, vi vil fjerne.

For eksempel hvis vi passerer “01”, fjerner de alle forreste 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 skal vi tilføje følgende afhængigheder til vores pom.xml fil:

 com.google.guava guava 27.0.1-jre 

Bemærk, at hvis vi vil bruge Guava i en Android-applikation, skal vi bruge versionen 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 henholdsvis enhver ledende eller efterfølgende karakter fra en Snor, der 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 de Apache Commons-metoder, vi så.

Derfor, hvis vi ikke ønsker at fjerne alle nuller, kan vi bruge det samme trick:

String removeLeadingZeroes (String s) {String stripped = CharMatcher.is ('0'). TrimLeadingFrom (s); hvis (stripped.isEmpty () &&! s.isEmpty ()) {return "0"; } returneret strippet; } String removeTrailingZeroes (String s) {String stripped = CharMatcher.is ('0'). TrimTrailingFrom (s); hvis (stripped.isEmpty () &&! s.isEmpty ()) {return "0"; } returneret strippet; }

Bemærk, at med CharMatcher vi kan oprette mere komplekse matchningsregler.

6. Brug af regulære udtryk

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

Oven i købet vil vi fjerne de matchende nuller. Med andre ord ønsker vi det udskift dem med intet eller med andre ord et tomt Snor.

Vi kan gøre netop det med String.replaceAll () metode:

String removeLeadingZeroes (String s) {return s.replaceAll ("^ 0+", ""); } Streng 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 måde med regulært udtryk at gøre dette på: Vi er nødt til at give et mønster, der ikke matcher helheden Snor.

På den måde, hvis input kun indeholder nuller, holder regexp-motoren nøjagtigt en ude af matchningen. Vi kan gøre dette med følgende mønstre:

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

Noter det “(?!^)” og “(?!$)” betyder, at det ikke er begyndelsen eller slutningen af Snor henholdsvis.

7. Konklusion

I denne vejledning så vi flere måder at fjerne ledende og efterfølgende tegn fra en Snor. Valget mellem disse implementeringer er ofte simpelthen personlig præference.

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