Jak usunąć zera wiodące z tekstu alfanumerycznego?

228

Widziałem pytania, jak przedrostek zer tutaj w SO. Ale nie na odwrót!

Czy możecie mi zasugerować, jak usunąć wiodące zera w tekście alfanumerycznym? Czy są jakieś wbudowane interfejsy API lub czy muszę napisać metodę przycinania zer wiodących?

Przykład:

01234 converts to 1234
0001234a converts to 1234a
001234-a converts to 1234-a
101234 remains as 101234
2509398 remains as 2509398
123z remains as 123z
000002829839 converts to 2829839
jai
źródło

Odpowiedzi:

617

Regex jest najlepszym narzędziem do pracy; to, co powinno być, zależy od specyfikacji problemu. Poniższe usuwa wiodące zera, ale pozostawia jeden, jeśli to konieczne (tzn. Nie zmieniłby się po prostu "0"w pusty ciąg).

s.replaceFirst("^0+(?!$)", "")

^Kotwica będzie upewnić się, że 0+jest dopasowana jest na początku wejścia. Te (?!$)negatywne, zapewnia uprzedzona, że nie cały ciąg zostaną dopasowane.

Uprząż testowa:

String[] in = {
    "01234",         // "[1234]"
    "0001234a",      // "[1234a]"
    "101234",        // "[101234]"
    "000002829839",  // "[2829839]"
    "0",             // "[0]"
    "0000000",       // "[0]"
    "0000009",       // "[9]"
    "000000z",       // "[z]"
    "000000.z",      // "[.z]"
};
for (String s : in) {
    System.out.println("[" + s.replaceFirst("^0+(?!$)", "") + "]");
}

Zobacz też

środki smarujące wielotlenowe
źródło
21
Dziękuję Ci. I bezlitośnie testowałeś;) Świetnie !! +1 za testy.
jai
4
@Greg: To pytanie dotyczy Javy, a nie JavaScript. Java SE ma metodę String.replaceFirst () od wersji 1.4.
Jonik
5
dodanie trim () do s.replaceFirst („^ 0 + (?! $)”, „”) (tj. s.trim (). replaceFirst („^ 0 + (?! $)”, „”) pomoże w usuwaniu spacji!
AVA
2
czy wyrażenie regularne nie jest trochę drogie jak na tak proste zadanie?
demongolem
5
To nie działa w Kotlinie, musisz wyraźnie powiedzieć o .replaceFirst("^0+(?!$)".toRegex(), "")
Regexie
100

Możesz użyć klasy StringUtils z Apache Commons Lang w następujący sposób:

StringUtils.stripStart(yourString,"0");
Hamilton Rodrigues
źródło
Czy ma to problem z samym „0”? @Hamilton Rodrigues
PhoonOne
2
Jeśli używasz tego samego „0”, zwraca „”. Uważaj więc, jeśli nie jest to wymagany efekt.
dARKpRINCE
Pozytywna opinia, ponieważ działa w przypadkach użycia w zadanym pytaniu. Pomógł mi tutaj również w szybkim rozwiązaniu. Dzięki!
Gabriel Amazonas Mesquita
32

Co powiesz na sposób wyrażenia regularnego:

String s = "001234-a";
s = s.replaceFirst ("^0*", "");

Do ^kotwy do początku łańcucha (jestem zakładając z kontekstu struny nie są multi-line tutaj, w przeciwnym razie może trzeba spojrzeć \Ana początku wejścia zamiast początku linii). Te 0*środki zero lub więcej 0znaków (użytkownik mógł korzystać 0+również). Po replaceFirstprostu zastępuje wszystkie te 0postacie na początku niczym.

A jeśli, podobnie jak Vadzim, twoja definicja zer wiodących nie obejmuje zamiany "0"(lub "000"podobnych ciągów) na pusty ciąg (wystarczająco racjonalne oczekiwanie), po prostu odłóż go, jeśli to konieczne:

String s = "00000000";
s = s.replaceFirst ("^0*", "");
if (s.isEmpty()) s = "0";
paxdiablo
źródło
6
Ma problem z samym „0”.
Vadzim
23

Przejrzysty sposób bez potrzeby regExp i bibliotek zewnętrznych.

public static String trimLeadingZeros(String source) {
    for (int i = 0; i < source.length(); ++i) {
        char c = source.charAt(i);
        if (c != '0') {
            return source.substring(i);
        }
    }
    return ""; // or return "0";
}
magik
źródło
1
Chociaż twoje sprawdzenie miejsca nie jest zgodne z pytaniem, niemniej myślę, że twoja odpowiedź wykona się najszybciej.
John Fowler
@JohnFowler 10x za połów, naprawiony po
ponad
1
A metoda wymaga powrotu na końcu, jeśli pętla znajdzie tylko zera. powrót ""; lub zwróć „0”; jeśli chcesz przynajmniej jeden zero
slipperyseal
@slipperyseal Zostawiłem to otwarte, abyś mógł je zmienić w zależności od potrzeb, ale ponieważ ludzie mają tendencję do kopiowania / wklejania, nie jest złym pomysłem, aby zawsze mieć domyślne zachowanie. dzięki za komentarz
magiccrafter
14

Aby przejść do odpowiedzi Apache Commons thelost: używając bibliotek guava ( biblioteki narzędziowej Java firmy Google, która, jak twierdzę, powinna znajdować się na ścieżce klasowej każdego nietrywialnego projektu Java), użyłaby CharMatchera :

CharMatcher.is('0').trimLeadingFrom(inputString);
Cowan
źródło
+1, poprawna odpowiedź dla każdego projektu korzystającego z Guava. (A teraz w 2012 r. Powinno to znaczyć prawie każdy projekt Java.)
Jonik
1
@Cowan Czy ma to problem z samym „0”? Will CharMatcher.is („0”). TrimLeadingFrom („0”); Zwraca „0” lub pusty ciąg?
PhoonOne
@PhoonOne: Właśnie to przetestowałem; zwraca pusty ciąg.
Stephan202
10

Jeśli korzystasz z Kotlin Jest to jedyny potrzebny kod:

yourString.trimStart('0')
Saman Sattari
źródło
5

Możesz po prostu zrobić: String s = Integer.valueOf("0001007").toString();

Damjan
źródło
2
Nie obsługuje alfanumerycznych.
slaman
4

Użyj StringUtilsklasy Apache Commons :

StringUtils.strip(String str, String stripChars);
thelost
źródło
2
OSTRZEŻENIE! Spowoduje to usunięcie zer wiodących i końcowych, co może nie być tym, czego chcesz.
Jens Bannmann,
18
Możesz usunąć tylko wiodące zera za pomocą StringUtils.stripStart ().
Josh Rosen
3

Użyj tego:

String x = "00123".replaceAll("^0*", ""); // -> 123
Eduardo Cuomo
źródło
2

Używanie Regexp z grupami:

Pattern pattern = Pattern.compile("(0*)(.*)");
String result = "";
Matcher matcher = pattern.matcher(content);
if (matcher.matches())
{
      // first group contains 0, second group the remaining characters
      // 000abcd - > 000, abcd
      result = matcher.group(2);
}

return result;
brj
źródło
2

Użycie wyrażenia regularnego, jak sugerują niektóre odpowiedzi, jest dobrym sposobem na zrobienie tego. Jeśli nie chcesz używać wyrażenia regularnego, możesz użyć tego kodu:

String s = "00a0a121";

while(s.length()>0 && s.charAt(0)=='0')
{
   s = s.substring(1); 
}
Hüseyin Burhan ÖZKAN
źródło
To może stworzyć wiele String... zamiast tego użyj narzędzia Magiccrafter .
AxelH
1

Myślę, że tak łatwo to zrobić. Możesz po prostu zapętlić ciąg od początku i usuwać zera, aż znajdziesz niezerowy znak.

int lastLeadZeroIndex = 0;
for (int i = 0; i < str.length(); i++) {
  char c = str.charAt(i);
  if (c == '0') {
    lastLeadZeroIndex = i;
  } else {
    break;
  }
}

str = str.subString(lastLeadZeroIndex+1, str.length());
Vodkhang
źródło
1

Jeśli (podobnie jak ja) musisz usunąć wszystkie zera wiodące z każdego „słowa” w ciągu, możesz zmodyfikować odpowiedź @polygenelubricants na następujące:

String s = "003 d0g 00ss 00 0 00";
s.replaceAll("\\b0+(?!\\b)", "");

Co skutkuje w:

3 d0g ss 0 0 0
xdhmoore
źródło
1

Bez użycia Regexlub substring()funkcji, na Stringktórych będzie nieefektywny -

public static String removeZero(String str){
        StringBuffer sb = new StringBuffer(str);
        while (sb.length()>1 && sb.charAt(0) == '0')
            sb.deleteCharAt(0);
        return sb.toString();  // return in String
    }
Sachin Aggarwal
źródło
0

Możesz zamienić "^0*(.*)"na na "$1"regex

TY
źródło
1
Jedyny problem, jaki tu widzę, to to, że może zastąpić puste zero „0”.
Dilipkumar J
0
       String s="0000000000046457657772752256266542=56256010000085100000";      
    String removeString="";

    for(int i =0;i<s.length();i++){
      if(s.charAt(i)=='0')
        removeString=removeString+"0";
      else 
        break;
    }

    System.out.println("original string - "+s);

    System.out.println("after removing 0's -"+s.replaceFirst(removeString,""));
Ajit Kumar Sahu
źródło
0

Jeśli nie chcesz używać wyrażenia regularnego lub biblioteki zewnętrznej. Możesz zrobić z „for”:

String input="0000008008451"
String output = input.trim();
for( ;output.length() > 1 && output.charAt(0) == '0'; output = output.substring(1));

System.out.println(output);//8008451
kfatih
źródło
Zbyt wiele Stringwygenerowanych podczas tej pętli ... jeśli jest ich 1000 0...
AxelH
0

Przeprowadziłem kilka testów porównawczych i odkryłem, że najszybszym (jak dotąd) sposobem jest to rozwiązanie:

    private static String removeLeadingZeros(String s) {
      try {
          Integer intVal = Integer.parseInt(s);
          s = intVal.toString();
      } catch (Exception ex) {
          // whatever
      }
      return s;
    }

Zwłaszcza wyrażenia regularne są bardzo powolne w długiej iteracji. (Musiałem znaleźć najszybszy sposób na partię).

Robert Fornesdale
źródło
-2

A może po prostu poszukiwanie pierwszego niezerowego znaku?

[1-9]\d+

Wyrażenie regularne znajduje pierwszą cyfrę od 1 do 9, po której następuje dowolna liczba cyfr, więc dla „00012345” zwraca „12345” . Można go łatwo dostosować do ciągów alfanumerycznych.

Czosnek Sol
źródło
To również nie pozwoli na zero.
Nishant Dongare