Comment supprimer les zéros non significatifs d'un texte alphanumérique?


229

J'ai vu des questions sur la façon de préfixer les zéros ici dans SO. Mais pas l'inverse!

Pouvez-vous me suggérer comment supprimer les zéros de tête dans le texte alphanumérique? Existe-t-il des API intégrées ou dois-je écrire une méthode pour couper les zéros non significatifs?

Exemple:

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

Réponses:


618

Regex est le meilleur outil pour le travail; ce que cela devrait être dépend de la spécification du problème. Ce qui suit supprime les zéros non significatifs, mais en laisse un si nécessaire (c'est-à-dire qu'il ne se transformerait pas simplement "0"en une chaîne vide).

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

L' ^ancre s'assurera que l' 0+appariement est au début de l'entrée. Le (?!$)lookahead négatif garantit que la chaîne entière ne sera pas mise en correspondance.

Harnais de test:

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

Voir également


21
Je vous remercie. Et vous avez testé sans pitié;) Génial !! +1 pour les tests.
jai

4
@Greg: Cette question concerne Java, pas JavaScript. Java SE possède la méthode String.replaceFirst () depuis la version 1.4.
Jonik

5
l'ajout de trim () à s.replaceFirst ("^ 0 + (?! $)", "") (ie. s.trim (). replaceFirst ("^ 0 + (?! $)", "") aidera en supprimant les espaces rembourrés
AVA

2
l'expression rationnelle n'est-elle pas un peu chère pour une tâche aussi simple?
demongolem

5
Cela ne fonctionne pas dans Kotlin, vous devez être explicite sur le Regex.replaceFirst("^0+(?!$)".toRegex(), "")
mkabatek

101

Vous pouvez utiliser la classe StringUtils d' Apache Commons Lang comme ceci:

StringUtils.stripStart(yourString,"0");

Est-ce que cela a un problème avec "0" seul? @Hamilton Rodrigues
PhoonOne

2
Si vous utilisez ceci sur "0" seul, cela rend "". Faites donc attention si ce n'est pas l'effet souhaité.
dARKpRINCE

Vote positif car cela fonctionne pour les cas d'utilisation de la question posée. M'a aidé ici aussi pour une solution rapide. THX!
Gabriel Amazonas Mesquita

32

Que diriez-vous de la manière regex:

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

Les ^ancres au début de la chaîne (je suppose que, selon le contexte, vos chaînes ne sont pas multilignes ici, sinon vous devrez peut-être rechercher le \Adébut de l'entrée plutôt que le début de la ligne). Le 0*signifie zéro ou plusieurs 0caractères (vous pouvez également les utiliser 0+). Le replaceFirstremplace simplement tous ces 0personnages au début par rien.

Et si, comme Vadzim, votre définition des zéros non significatifs n'inclut pas de transformer "0"(ou "000"des chaînes similaires) en une chaîne vide (une attente suffisamment rationnelle), remettez-la simplement si nécessaire:

String s = "00000000";
s = s.replaceFirst ("^0*", "");
if (s.isEmpty()) s = "0";

6
Il a un problème avec "0" seul.
Vadzim

23

Un moyen clair sans avoir besoin de regExp et de bibliothèques externes.

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

1
Bien que votre vérification d'espace ne soit pas conforme à la question, je pense néanmoins que votre réponse s'exécutera le plus rapidement.
John Fowler du

@JohnFowler 10x pour la capture, fixé après 2 ans et plus
magiccrafter

1
Et la méthode a besoin d'un retour à la fin si la boucle ne trouve que des zéros. revenir ""; ou retourner "0"; si vous voulez au moins un zéro
slipperyseal

@slipperyseal Je l'ai laissé ouvert pour que vous puissiez le changer en fonction de vos besoins, mais comme les gens ont tendance à copier / coller, ce n'est pas une mauvaise idée d'avoir toujours un comportement par défaut. merci pour le commentaire
magiccrafter

14

Pour aller avec la réponse d'Apache Commons de thelost: en utilisant les bibliothèques de goyaves (la bibliothèque d'utilitaires Java à usage général de Google qui, selon moi, devrait maintenant être sur le chemin de classe de tout projet Java non trivial), cela utiliserait CharMatcher :

CharMatcher.is('0').trimLeadingFrom(inputString);

+1, la bonne réponse pour tout projet utilisant la goyave. (Et maintenant en 2012, cela devrait signifier à peu près n'importe quel projet Java.)
Jonik

1
@Cowan Cela a-t-il un problème avec "0" seul? Will CharMatcher.is ('0'). TrimLeadingFrom ("0"); Renvoyer le "0" ou une chaîne vide?
PhoonOne

@PhoonOne: Je viens de tester cela; il renvoie la chaîne vide.
Stephan202

10

Si vous utilisez Kotlin C'est le seul code dont vous avez besoin:

yourString.trimStart('0')

5

Vous pourriez simplement faire: String s = Integer.valueOf("0001007").toString();


2
Ne gère pas les caractères alphanumériques.
slaman

4

Utilisez la StringUtilsclasse Apache Commons :

StringUtils.strip(String str, String stripChars);

2
AVERTISSEMENT! Cela supprimera les zéros de début et de fin, ce qui n'est peut-être pas ce que vous voulez.
Jens Bannmann

18
Vous pouvez supprimer uniquement les zéros non significatifs à l'aide de StringUtils.stripStart ().
Josh Rosen


2

Utilisation de Regexp avec des groupes:

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;

2

Utiliser l'expression régulière comme le suggèrent certaines des réponses est un bon moyen de le faire. Si vous ne souhaitez pas utiliser l'expression régulière, vous pouvez utiliser ce code:

String s = "00a0a121";

while(s.length()>0 && s.charAt(0)=='0')
{
   s = s.substring(1); 
}

Cela pourrait créer beaucoup de String... utiliser l' approche de magiccrafter à la place.
AxelH

1

Je pense que c'est si facile de faire ça. Vous pouvez simplement parcourir la chaîne depuis le début et supprimer les zéros jusqu'à ce que vous trouviez un caractère non nul.

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

1

Si vous (comme moi) devez supprimer tous les zéros de tête de chaque "mot" d'une chaîne, vous pouvez modifier la réponse de @polygenelubricants aux éléments suivants:

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

ce qui se traduit par:

3 d0g ss 0 0 0

1

Sans utiliser Regexni substring()fonction sur Stringlaquelle sera inefficace -

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
    }

0

Vous pouvez remplacer "^0*(.*)"to "$1"par regex


1
Le seul problème que je vois ici est que cela pourrait remplacer un zéro solitaire «0» par un blanc.
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,""));

0

Si vous ne souhaitez pas utiliser regex ou bibliothèque externe. Vous pouvez faire avec "pour":

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

System.out.println(output);//8008451

Trop de Stringgénérés pendant cette boucle ... s'il y en a 1000 0...
AxelH

0

J'ai fait quelques tests de référence et constaté que le moyen le plus rapide (de loin) est cette solution:

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

Les expressions particulièrement régulières sont très lentes dans une longue itération. (J'avais besoin de trouver le moyen le plus rapide pour un batchjob.)


-2

Et qu'en est-il de la recherche du premier caractère non nul?

[1-9]\d+

Cette expression régulière trouve le premier chiffre entre 1 et 9 suivi d'un nombre quelconque de chiffres, donc pour "00012345", il renvoie "12345" . Il peut être facilement adapté aux chaînes alphanumériques.


Cela ne permettra pas non plus le zéro par la suite.
Nishant Dongare
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.