Wie entferne ich führende Nullen aus alphanumerischem Text?

226

Ich habe Fragen zum Präfixieren von Nullen hier in SO gesehen. Aber nicht umgekehrt!

Könnt ihr mir vorschlagen, wie man die führenden Nullen im alphanumerischen Text entfernt? Gibt es integrierte APIs oder muss ich eine Methode schreiben, um die führenden Nullen zu trimmen?

Beispiel:

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
quelle

Antworten:

615

Regex ist das beste Werkzeug für diesen Job. Was es sein sollte, hängt von der Problemspezifikation ab. Im Folgenden werden führende Nullen entfernt, aber bei Bedarf eine belassen (dh es wird nicht einfach "0"eine leere Zeichenfolge verwendet).

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

Der ^Anker stellt sicher, dass sich die 0+Übereinstimmung am Anfang der Eingabe befindet. Der (?!$)negative Lookahead stellt sicher, dass nicht die gesamte Zeichenfolge übereinstimmt.

Prüfkabel:

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+(?!$)", "") + "]");
}

Siehe auch

Polygenschmierstoffe
quelle
21
Danke dir. Und du hast rücksichtslos getestet;) Großartig !! +1 für die Tests.
Jai
4
@ Greg: Diese Frage bezieht sich auf Java, nicht auf JavaScript. Java SE hat seit Version 1.4 die Methode String.replaceFirst () .
Jonik
5
Das Hinzufügen von trim () zu s.replaceFirst ("^ 0 + (?! $)", "") (dh s.trim (). replaceFirst ("^ 0 + (?! $)", "") hilft beim Entfernen von gepolsterten Leerzeichen!
AVA
2
Ist Regex für eine so einfache Aufgabe nicht ein bisschen teuer?
Demongolem
5
Dies funktioniert nicht in Kotlin, Sie müssen explizit über die Regex.replaceFirst("^0+(?!$)".toRegex(), "")
mkabatek
99

Sie können die StringUtils- Klasse von Apache Commons Lang folgendermaßen verwenden :

StringUtils.stripStart(yourString,"0");
Hamilton Rodrigues
quelle
Hat dies ein Problem mit "0" allein? @ Hamilton Rodrigues
PhoonOne
2
Wenn Sie dies nur für "0" verwenden, wird "" zurückgegeben. Seien Sie also vorsichtig, wenn dies nicht der gewünschte Effekt ist.
DARKPRINCE
Upvoted Ursache funktioniert es für die Anwendungsfälle in der gestellten Frage. Hat mir auch hier für eine schnelle Lösung geholfen. Vielen Dank!
Gabriel Amazonas Mesquita
32

Wie wäre es mit dem Regex-Weg:

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

Die ^Anker am Anfang der Zeichenfolge (ich gehe aus dem Kontext davon aus, dass Ihre Zeichenfolgen hier nicht mehrzeilig sind, andernfalls müssen Sie möglicherweise \Aeher nach dem Beginn der Eingabe als nach dem Beginn der Zeile suchen ). Das 0*bedeutet null oder mehr 0Zeichen (Sie können auch verwenden 0+). Das replaceFirstersetzt einfach alle diese 0Zeichen am Anfang durch nichts.

Und wenn Ihre Definition von führenden Nullen wie bei Vadzim nicht darin besteht, "0"(oder "000"ähnliche Zeichenfolgen) in eine leere Zeichenfolge umzuwandeln (eine ausreichend vernünftige Erwartung), setzen Sie sie bei Bedarf einfach zurück:

String s = "00000000";
s = s.replaceFirst ("^0*", "");
if (s.isEmpty()) s = "0";
paxdiablo
quelle
6
Es hat ein Problem mit "0" allein.
Vadzim
22

Ein klarer Weg ohne die Notwendigkeit von regExp und externen Bibliotheken.

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";
}
Zauberkünstler
quelle
1
Obwohl Ihre Überprüfung auf Platz nicht der Frage entspricht, denke ich, dass Ihre Antwort am schnellsten ausgeführt werden würde.
John Fowler
@ JohnFowler 10x für den Fang, nach 2+ Jahren
behoben
1
Und die Methode benötigt am Ende eine Rückgabe, wenn die Schleife nur Nullen findet. Rückkehr ""; oder "0" zurückgeben; wenn Sie mindestens eine Null wollen
Slipperyseal
@slipperyseal Ich habe es offen gelassen, damit Sie es je nach Ihren Anforderungen ändern können. Da die Leute jedoch zum Kopieren / Einfügen neigen, ist es keine schlechte Idee, immer ein Standardverhalten zu haben. danke für den Kommentar
magiccrafter
14

Passend zum thelost Apache Commons Antwort: mit Guave-Bibliotheken (Google-Allzweck-Java - Utility - Bibliothek , die ich argumentieren würde jetzt auf dem Classpath eines nicht-triviale Java - Projekt sein sollte), würde dies verwenden CharMatcher :

CharMatcher.is('0').trimLeadingFrom(inputString);
Cowan
quelle
+1, die richtige Antwort für jedes Projekt, das Guava verwendet. (Und jetzt im Jahr 2012 sollte das so ziemlich jedes Java-Projekt bedeuten.)
Jonik
1
@Cowan Hat dies ein Problem mit "0" allein? Will CharMatcher.is ('0'). TrimLeadingFrom ("0"); "0" oder leere Zeichenfolge zurückgeben?
PhoonOne
@PhoonOne: Ich habe das gerade getestet. es gibt die leere Zeichenfolge zurück.
Stephan202
9

Wenn Sie Kotlin verwenden Dies ist der einzige Code, den Sie benötigen:

yourString.trimStart('0')
Saman Sattari
quelle
5

Sie könnten einfach tun: String s = Integer.valueOf("0001007").toString();

Damjan
quelle
1
Wird nicht mit alphanumerischen Zeichen umgehen.
Slaman
4

Verwenden Sie die Apache Commons- StringUtilsKlasse:

StringUtils.strip(String str, String stripChars);
der Verlust
quelle
2
WARNUNG! Dadurch werden führende und endende Nullen entfernt, was möglicherweise nicht das ist, was Sie wollen.
Jens Bannmann
18
Mit StringUtils.stripStart () können Sie nur führende Nullen entfernen.
Josh Rosen
3

Benutze das:

String x = "00123".replaceAll("^0*", ""); // -> 123
Eduardo Cuomo
quelle
2

Verwenden von Regexp mit Gruppen:

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
quelle
2

Die Verwendung von Regex, wie einige der Antworten vermuten lassen, ist ein guter Weg, dies zu tun. Wenn Sie Regex nicht verwenden möchten, können Sie diesen Code verwenden:

String s = "00a0a121";

while(s.length()>0 && s.charAt(0)=='0')
{
   s = s.substring(1); 
}
Hüseyin Burhan ÖZKAN
quelle
Dies könnte viel Stringdazu führen, dass stattdessen MagicCrafter-Ansätze verwendet werden.
AxelH
1

Ich denke, dass es so einfach ist, das zu tun. Sie können die Zeichenfolge einfach von Anfang an durchlaufen und Nullen entfernen, bis Sie ein Zeichen ungleich Null gefunden haben.

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());
Wodkhang
quelle
1

Wenn Sie (wie ich) alle führenden Nullen aus jedem "Wort" in einer Zeichenfolge entfernen müssen, können Sie die Antwort von @polygenelubricants wie folgt ändern:

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

was in ... endet:

3 d0g ss 0 0 0
xdhmoore
quelle
1

Ohne Verwendung Regexoder substring()Funktion, Stringdie ineffizient sein wird -

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
quelle
0

Sie könnten ersetzen , "^0*(.*)"um "$1"mit regex

SIE
quelle
1
Das einzige Problem, das ich hier sehe, ist, dass dies möglicherweise eine einzelne Null '0' durch eine leere ersetzt.
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
quelle
0

Wenn Sie keinen regulären Ausdruck oder keine externe Bibliothek verwenden möchten. Sie können mit "für" tun:

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
quelle
Zu viele Stringwährend dieser Schleife erzeugt ... wenn es 1000 gibt 0...
AxelH
0

Ich habe einige Benchmark-Tests durchgeführt und festgestellt, dass der schnellste Weg (bei weitem) diese Lösung ist:

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

Besonders reguläre Ausdrücke sind in einer langen Iteration sehr langsam. (Ich musste den schnellsten Weg für einen Batchjob herausfinden.)

Robert Fornesdale
quelle
-2

Und was ist mit der Suche nach dem ersten Zeichen ungleich Null?

[1-9]\d+

Diese Regex findet die erste Ziffer zwischen 1 und 9, gefolgt von einer beliebigen Anzahl von Ziffern. Für "00012345" wird also "12345" zurückgegeben . Es kann leicht für alphanumerische Zeichenfolgen angepasst werden.

Sol Knoblauch
quelle
Dies erlaubt auch danach keine Null mehr.
Nishant Dongare