Sur la question de la fonction apache vs le formateur de chaînes, il ne fait aucun doute que la fonction apache est plus claire et plus facile à lire. Envelopper le formateur dans les noms de fonction n'est pas idéal.
Mais veuillez noter que - comme d'autres l'ont mentionné et démontré dans cette réponse - String.format()et les Formatterclasses du JDK sont de meilleures options. Utilisez-les sur le code commun.
java.util.Formatter (et String.format ()) le fait. Préférez toujours le JDK à une bibliothèque externe si la version du JDK fait le travail (ce qu'il fait).
@Jonik voudriez-vous énumérer certaines de vos raisons? Les API se ressemblent à peu près.
glen3b
3
@ glen3b: Pour un utilitaire individuel, comme ces aides de remplissage de chaîne, la bibliothèque à utiliser ne fait aucune différence. Cela dit, Guava est dans l'ensemble une bibliothèque plus moderne, plus propre et mieux documentée que ses homologues dans divers projets Apache Commons (Commons Lang, Commons Collections, Commons IO, etc.). Il est également construit par des gars vraiment intelligents (Kevin Bourrillion et al), dont beaucoup sont actifs chez SO . Moi-même, j'ai fini par remplacer les diverses bibliothèques Apache Commons par seulement Guava il y a des années, et je n'ai aucun regret.
Et si vous avez besoin de lpad avec d'autres caractères (pas des espaces)? Est-il toujours possible avec String.format? Je ne suis pas en mesure de le faire fonctionner ...
@ Nullw0rm, si vous faites référence à rgagnon.com, sachez que RealHowTo est aussi l'auteur de rgagnon.com, donc il se créditerait ...
Colin Pickard
3
au moins sur ma JVM, le "#" ne fonctionne pas, le "-" est très bien. (Supprimez simplement le #). Cela peut être cohérent avec la documentation du formateur, je ne sais pas; il dit "'#' '\ u0023' Nécessite que la sortie utilise un autre formulaire. La définition du formulaire est spécifiée par la conversion."
gatoatigrado
6
Merci pour la réponse géniale. J'ai un doute cependant, à quoi ça sert 1$? @leo a fait une réponse très similaire qui n'utilise pas 1$et qui a apparemment le même effet. Est-ce que cela fait une différence?
Fabrício Matté
257
Rembourrage à 10 caractères:
String.format("%10s","foo").replace(' ','*');String.format("%-10s","bar").replace(' ','*');String.format("%10s","longer than 10 chars").replace(' ','*');
Aussi longtemps que nous nous souvenons tous de ne pas passer dans une chaîne avec des espaces ...: D
leviathanbadger
4
Je suis avec @ aboveyou00 - c'est une solution horrible pour les chaînes avec des espaces, y compris l'exemple fourni par leo. Une solution pour le remplissage d'une chaîne à gauche ou à droite ne doit pas modifier la chaîne d'entrée telle qu'elle apparaît dans la sortie, sauf si le remplissage d'origine de la chaîne d'entrée la fait dépasser la longueur de remplissage spécifiée.
Brian Warshaw
3
Reconnaissez le problème d'espace. .replace(' ', '*')était plutôt destiné à montrer l'effet du rembourrage. L'expression masquant le mot de passe n'a pas ce problème de toute façon ... Pour une meilleure réponse sur la personnalisation de la chaîne de remplissage gauche et droite en utilisant la fonctionnalité Java native, voir mon autre réponse.
leo
Si la chaîne ne contient que des espaces simples et que vous souhaitez ajouter des caractères différents, vous pouvez utiliser regex replace avec look behind / ahead: String.format("%30s", "pad left").replaceAll("(?<=( |^)) ", "*")ouString.format("%-30s", "pad right").replaceAll(" (?=( |$))", "*")
Faites attention: vous avez inversé les noms des fonctions; si vous l'exécutez, vous verrez.
bleuâtre
De plus, si la chaîne d'origine contient des espaces, cela ne fonctionne pas
Steven Shaw
@StevenShaw Si je ne me trompe pas, le remplacement ne cible pas l'original str, c'est donc correct.
mafu
3
Par convention, vous ne devez pas utiliser de majuscule pour les noms de fonction.
domaine-principal-idéal
Y at - il une condition manquante sur le retour de la chaîne comme est quand (length - str.length())est 0? Le formateur lance un FormatFlagsConversionMismatchExceptionquand %0sest la chaîne de format.
Devin Walters
7
Cela m'a pris un peu de temps pour comprendre. La vraie clé est de lire cette documentation Formatter.
// Get your data from wherever.finalbyte[] data = getData();// Get the digest engine.finalMessageDigest md5=MessageDigest.getInstance("MD5");// Send your data through it.
md5.update(data);// Parse the data as a positive BigInteger.finalBigInteger digest =newBigInteger(1,md5.digest());// Pad the digest with blanks, 32 wide.String hex =String.format(// See: http://download.oracle.com/javase/1.5.0/docs/api/java/util/Formatter.html// Format: %[argument_index$][flags][width]conversion// Conversion: 'x', 'X' integral The result is formatted as a hexadecimal integer"%1$32x",
digest
);// Replace the blank padding with 0s.
hex = hex.replace(" ","0");System.out.println(hex);
Pourquoi rendre la fin si compliquée? Vous auriez pu juste faire String hex = String.format ("% 032x", digest); et a eu exactement les mêmes résultats, juste sans un replace inutile () et d'avoir à utiliser le $ pour accéder à des variables spécifiques (il n'y en a qu'un, après tout.)
ArtOfWarfare
@ArtOfWarfare fair point. Quelqu'un a initialement demandé le remplissage des valeurs hexadécimales dans une autre question, j'ai vu que j'avais un lien vers la documentation du formateur. C'est compliqué pour être complet.
Nthalk
6
Je sais que ce fil est un peu ancien et la question d'origine était pour une solution facile, mais s'il est censé être très rapide, vous devez utiliser un tableau de caractères.
Si StringBuffervous ne pouvez pas accéder à plusieurs threads à la fois (ce qui est vrai dans ce cas), vous devez utiliser un StringBuilder(dans JDK1.5 +) pour éviter la surcharge de synchronisation.
glen3b
5
Voici une autre façon de vous déplacer vers la droite:
// put the number of spaces, or any character you like, in your paddedStringString paddedString ="--------------------";String myStringToBePadded ="I like donuts";
myStringToBePadded = myStringToBePadded + paddedString.substring(myStringToBePadded.length());//result:
myStringToBePadded ="I like donuts-------";
Vous pouvez également faire de la longueur du résultat un paramètre de la pad(...)méthode. Dans ce cas, ajustez le remplissage masqué dans cette méthode plutôt que dans le constructeur.
(Astuce: pour un crédit supplémentaire, rendez-le thread-safe! ;-)
C'est sûr pour les threads, sauf pour les publications non sécurisées (rendez vos champs définitifs, bien sûr). Je pense que les performances pourraient être améliorées en faisant une sous-chaîne avant le + qui devrait être remplacée par concat (curieusement).
Il remplira votre chaîne XXX jusqu'à 9 caractères avec un espace. Après cela, tous les espaces blancs seront remplacés par un 0. Vous pouvez changer l'espace blanc et le 0 en ce que vous voulez ...
Vous devez invoquer la staticméthode as String.format(…)au lieu d'abuser d'une chaîne vide. L'enregistrement de quatre caractères dans le code source ne vaut certainement pas la perte de lisibilité.
Holger
2
publicstaticString padLeft(String in,int size,char padChar){if(in.length()<= size){char[] temp =newchar[size];/* Llenado Array con el padChar*/for(int i =0;i<size;i++){
temp[i]= padChar;}int posIniTemp = size-in.length();for(int i=0;i<in.length();i++){
temp[posIniTemp]=in.charAt(i);
posIniTemp++;}returnnewString(temp);}return"";}
Permettez-moi de laisser une réponse pour certains cas que vous devez donner un remplissage gauche / droite (ou une chaîne de préfixe / suffixe ou des espaces) avant de concaténer une autre chaîne et vous ne voulez pas tester la longueur ou toute condition if.
De même pour la réponse choisie, je préférerais StringUtilsApache Commons mais en utilisant cette façon:
Les réponses de @ck et @Marlon Tarak sont les seules à utiliser a char[], ce qui est la meilleure approche pour les applications qui ont plusieurs appels aux méthodes de remplissage par seconde. Cependant, ils ne profitent d'aucune optimisation de manipulation de tableau et sont un peu écrasés à mon goût; cela peut être fait sans boucles du tout .
publicstaticvoid main(String... args){System.out.println("012345678901234567890123456789");System.out.println(pad("cats",' ',30,true));System.out.println(pad("cats",' ',30,false));System.out.println(pad("cats",' ',20,false));System.out.println(pad("cats",'$',30,true));System.out.println(pad("too long for your own good, buddy",'#',30,true));}
Les sorties:
012345678901234567890123456789
cats
cats
cats
cats$$$$$$$$$$$$$$$$$$$$$$$$$$
too longfor your own good, buddy
Vous pouvez utiliser getCharspour laisser la Stringcopie de son contenu directement dans le outtableau, au lieu d'appeler source.toCharArray(), suivi de System.arraycopy. J'envisagerais même de simplifier la mise en œuvre pour char[] out = new char[length]; Arrays.fill(out, 0, length, fill); source.getChars(0, source.length(), out, right? 0: length - source.length()); return new String(out);; bien que cela semble fillfaire plus de travail, cela permet en fait à la JVM d'éliminer le remplissage par défaut.
Holger
1
java.util.Formatterfera un rembourrage gauche et droit. Pas besoin de dépendances étranges de tiers (voudriez-vous les ajouter pour quelque chose de si trivial).
[J'ai laissé de côté les détails et créé cet article «wiki communautaire» car ce n'est pas quelque chose dont j'ai besoin.]
Je ne suis pas d'accord. Dans tout projet Java de plus grande envergure, vous ferez généralement autant de manipulations de chaînes, que la lisibilité accrue et l'évitement des erreurs valent bien l'utilisation d'Apache Commons Lang. Vous connaissez tous du code comme someString.subString (someString.indexOf (startCharacter), someString.lastIndexOf (endCharacter)), ce qui peut facilement être évité avec StringUtils.
Bananeweizen
1
Toutes les opérations de chaîne doivent généralement être très efficaces , en particulier si vous travaillez avec de grands ensembles de données. Je voulais quelque chose de rapide et flexible, similaire à ce que vous obtiendrez dans la commande plsql pad. De plus, je ne veux pas inclure une énorme bibliothèque pour juste une petite chose. Avec ces considérations, aucune de ces solutions n'était satisfaisante. Ce sont les solutions que j'ai trouvées, qui ont eu les meilleurs résultats d'analyse comparative, si quelqu'un peut l'améliorer, veuillez ajouter votre commentaire.
notez qu'il est appelé avec String.toCharArray () et que le résultat peut être converti en String avec un nouveau String ((char []) résultat). La raison en est que si vous appliquez plusieurs opérations, vous pouvez toutes les faire sur char [] et ne pas continuer à convertir entre les formats - en arrière-plan, String est stocké en tant que char []. Si ces opérations avaient été incluses dans la classe String elle-même, elles auraient été deux fois plus efficaces - en termes de vitesse et de mémoire.
Que diriez-vous d'utiliser la récursivité? La solution donnée ci-dessous est compatible avec toutes les versions JDK et aucune bibliothèque externe requise :)
privatestaticString addPadding(finalString str,finalint desiredLength,finalString padBy){String result = str;if(str.length()>= desiredLength){return result;}else{
result += padBy;return addPadding(result, desiredLength, padBy);}}
REMARQUE : Cette solution ajoutera le remplissage, avec un petit ajustement, vous pouvez préfixer la valeur du tampon.
Voici une version parallèle pour ceux d'entre vous qui ont de très longues cordes :-)
int width =100;String s ="129018";CharSequence padded =IntStream.range(0,width).parallel().map(i->i-(width-s.length())).map(i->i<0?'0':s.charAt(i)).collect(StringBuilder::new,(sb,c)-> sb.append((char)c),(sb1,sb2)->sb1.append(sb2));
Réponses:
Apache
StringUtils
a plusieurs méthodes:leftPad
,rightPad
,center
etrepeat
.Mais veuillez noter que - comme d'autres l'ont mentionné et démontré dans cette réponse -
String.format()
et lesFormatter
classes du JDK sont de meilleures options. Utilisez-les sur le code commun.la source
Depuis Java 1.5,
String.format()
peut être utilisé pour remplir à gauche / droite une chaîne donnée.Et la sortie est:
la source
1$
? @leo a fait une réponse très similaire qui n'utilise pas1$
et qui a apparemment le même effet. Est-ce que cela fait une différence?Rembourrage à 10 caractères:
production:
Afficher '*' pour les caractères du mot de passe:
la sortie a la même longueur que la chaîne de mot de passe:
la source
.replace(' ', '*')
était plutôt destiné à montrer l'effet du rembourrage. L'expression masquant le mot de passe n'a pas ce problème de toute façon ... Pour une meilleure réponse sur la personnalisation de la chaîne de remplissage gauche et droite en utilisant la fonctionnalité Java native, voir mon autre réponse.String.format("%30s", "pad left").replaceAll("(?<=( |^)) ", "*")
ouString.format("%-30s", "pad right").replaceAll(" (?=( |$))", "*")
À la goyave , c'est facile:
la source
Quelque chose de simple:
La valeur doit être une chaîne. le convertir en chaîne, si ce n'est pas le cas. Comme
"" + 123
ouInteger.toString(123)
La sous-chaîne commence à partir de l'indice de longueur de la valeur de la valeur jusqu'à la longueur de fin du remplissage:
Plus précis
pad droit:
pad gauche:
la source
Jetez un oeil à
org.apache.commons.lang.StringUtils#rightPad(String str, int size, char padChar)
.Mais l'algorithme est très simple (pad jusqu'à la taille des caractères):
la source
Outre Apache Commons, voyez également
String.format
qui devrait être capable de prendre en charge le remplissage simple (par exemple avec des espaces).la source
la source
str
, c'est donc correct.(length - str.length())
est0
? Le formateur lance unFormatFlagsConversionMismatchException
quand%0s
est la chaîne de format.Cela m'a pris un peu de temps pour comprendre. La vraie clé est de lire cette documentation Formatter.
la source
Je sais que ce fil est un peu ancien et la question d'origine était pour une solution facile, mais s'il est censé être très rapide, vous devez utiliser un tableau de caractères.
la solution de formateur n'est pas optimale. la construction de la chaîne de formatage crée 2 nouvelles chaînes.
La solution d'Apache peut être améliorée en initialisant le sb avec la taille cible afin de remplacer ci-dessous
avec
empêcherait le tampon interne du sb de croître.
la source
StringBuffer
vous ne pouvez pas accéder à plusieurs threads à la fois (ce qui est vrai dans ce cas), vous devez utiliser unStringBuilder
(dans JDK1.5 +) pour éviter la surcharge de synchronisation.Voici une autre façon de vous déplacer vers la droite:
la source
Depuis Java 11, String.repeat (int) peut être utilisé pour remplir à gauche / droite une chaîne donnée.
Production:
la source
Vous pouvez réduire la surcharge par appel en conservant les données de remplissage, plutôt que de les reconstruire à chaque fois:
Vous pouvez également faire de la longueur du résultat un paramètre de la
pad(...)
méthode. Dans ce cas, ajustez le remplissage masqué dans cette méthode plutôt que dans le constructeur.(Astuce: pour un crédit supplémentaire, rendez-le thread-safe! ;-)
la source
J'ai trouvé ça sur Dzone
Pad avec zéros:
la source
vous pouvez utiliser les méthodes intégrées StringBuilder append () et insert (), pour le remplissage de longueurs de chaîne variables:
Par exemple:
la source
Cela marche:
Il remplira votre chaîne XXX jusqu'à 9 caractères avec un espace. Après cela, tous les espaces blancs seront remplacés par un 0. Vous pouvez changer l'espace blanc et le 0 en ce que vous voulez ...
la source
static
méthode asString.format(…)
au lieu d'abuser d'une chaîne vide. L'enregistrement de quatre caractères dans le code source ne vaut certainement pas la perte de lisibilité.la source
Permettez-moi de laisser une réponse pour certains cas que vous devez donner un remplissage gauche / droite (ou une chaîne de préfixe / suffixe ou des espaces) avant de concaténer une autre chaîne et vous ne voulez pas tester la longueur ou toute condition if.
De même pour la réponse choisie, je préférerais
StringUtils
Apache Commons mais en utilisant cette façon:Explique:
myString
: la chaîne que j'entre, peut être nulleStringUtils.leftPad(myString, 1)
: si la chaîne est nulle, cette instruction retournerait aussi nulldefaultString
pour donner une chaîne vide pour éviter de concaténer nullla source
Les réponses de @ck et @Marlon Tarak sont les seules à utiliser a
char[]
, ce qui est la meilleure approche pour les applications qui ont plusieurs appels aux méthodes de remplissage par seconde. Cependant, ils ne profitent d'aucune optimisation de manipulation de tableau et sont un peu écrasés à mon goût; cela peut être fait sans boucles du tout .Méthode d'essai simple:
Les sorties:
la source
getChars
pour laisser laString
copie de son contenu directement dans leout
tableau, au lieu d'appelersource.toCharArray()
, suivi deSystem.arraycopy
. J'envisagerais même de simplifier la mise en œuvre pourchar[] out = new char[length]; Arrays.fill(out, 0, length, fill); source.getChars(0, source.length(), out, right? 0: length - source.length()); return new String(out);
; bien que cela semblefill
faire plus de travail, cela permet en fait à la JVM d'éliminer le remplissage par défaut.java.util.Formatter
fera un rembourrage gauche et droit. Pas besoin de dépendances étranges de tiers (voudriez-vous les ajouter pour quelque chose de si trivial).[J'ai laissé de côté les détails et créé cet article «wiki communautaire» car ce n'est pas quelque chose dont j'ai besoin.]
la source
Toutes les opérations de chaîne doivent généralement être très efficaces , en particulier si vous travaillez avec de grands ensembles de données. Je voulais quelque chose de rapide et flexible, similaire à ce que vous obtiendrez dans la commande plsql pad. De plus, je ne veux pas inclure une énorme bibliothèque pour juste une petite chose. Avec ces considérations, aucune de ces solutions n'était satisfaisante. Ce sont les solutions que j'ai trouvées, qui ont eu les meilleurs résultats d'analyse comparative, si quelqu'un peut l'améliorer, veuillez ajouter votre commentaire.
la source
Utilisez cette fonction.
comment utiliser?
sortie: 01 02 03 04 .. 11 12
la source
Beaucoup de gens ont des techniques très intéressantes mais j'aime rester simple donc je vais avec ceci:
la source
Une solution simple sans aucune API sera la suivante:
la source
Oneliners Java, pas de bibliothèque de fantaisie.
Pad gauche, ne pas limiter
Pad Right, ne pas limiter
Pad gauche, limite à la longueur du pad
Pad Right, limite à la longueur du pad
la source
Que diriez-vous d'utiliser la récursivité? La solution donnée ci-dessous est compatible avec toutes les versions JDK et aucune bibliothèque externe requise :)
REMARQUE : Cette solution ajoutera le remplissage, avec un petit ajustement, vous pouvez préfixer la valeur du tampon.
la source
Voici une version parallèle pour ceux d'entre vous qui ont de très longues cordes :-)
la source
Exemples de remplissage en goyave:
Exemples de remplissage dans Apache Commons:
Exemples de remplissage dans JDK:
la source
Une solution simple serait:
la source
Comment est-ce
La chaîne est "bonjour" et le remplissage requis est de 15 avec le tampon gauche "0"
la source