58 votes

Remplir à gauche ou à droite avec string.format (pas padleft ou padright) avec une chaîne arbitraire

Puis-je utiliser String.Format() pour compléter une certaine chaîne avec des caractères arbitraires ?

Console.WriteLine("->{0,18}<-", "hello");
Console.WriteLine("->{0,-18}<-", "hello");

returns 

->             hello<-
->hello             <-

Je veux maintenant que les espaces soient un caractère arbitraire. La raison pour laquelle je ne peux pas le faire avec padLeft ou padRight est que je veux pouvoir construire la chaîne de formatage à un endroit/temps différent de celui où le formatage est réellement exécuté.

--EDIT--
Vu qu'il ne semble pas y avoir de solution existante à mon problème, j'ai trouvé cette solution (après Suggestion de Think Before Coding )
--EDIT2--
J'avais besoin de scénarios plus complexes, alors j'ai opté pour Deuxième suggestion de Think Before Coding

[TestMethod]
public void PaddedStringShouldPadLeft() {
    string result = string.Format(new PaddedStringFormatInfo(), "->{0:20:x} {1}<-", "Hello", "World");
    string expected = "->xxxxxxxxxxxxxxxHello World<-";
    Assert.AreEqual(result, expected);
}
[TestMethod]
public void PaddedStringShouldPadRight()
{
    string result = string.Format(new PaddedStringFormatInfo(), "->{0} {1:-20:x}<-", "Hello", "World");
    string expected = "->Hello Worldxxxxxxxxxxxxxxx<-";
    Assert.AreEqual(result, expected);
}
[TestMethod]
public void ShouldPadLeftThenRight()
{
    string result = string.Format(new PaddedStringFormatInfo(), "->{0:10:L} {1:-10:R}<-", "Hello", "World");
    string expected = "->LLLLLHello WorldRRRRR<-";
    Assert.AreEqual(result, expected);
}
[TestMethod]
public void ShouldFormatRegular()
{
    string result = string.Format(new PaddedStringFormatInfo(), "->{0} {1:-10}<-", "Hello", "World");
    string expected = string.Format("->{0} {1,-10}<-", "Hello", "World");
    Assert.AreEqual(expected, result);
}

Comme le code était un peu trop volumineux pour être mis dans un post, je l'ai déplacé sur github en tant que gist :
http://gist.github.com/533905#file_padded_string_format_info

Les gens peuvent facilement s'y brancher et tout ce qu'ils veulent :)

0 votes

Je pense que vous devriez vous assurer que la chaîne n'est pas vide. Cela passerait-il le test : string.Fomat("{0}", (PaddedString) "Hello") ; ?

30voto

Think Before Coding Points 4151

Il existe une autre solution.

Mettre en œuvre IFormatProvider pour renvoyer un ICustomFormatter qui sera transmis à string.Format :

public class StringPadder : ICustomFormatter
{
  public string Format(string format, object arg,
       IFormatProvider formatProvider)
  {
     // do padding for string arguments
     // use default for others
  }
}

public class StringPadderFormatProvider : IFormatProvider
{
  public object GetFormat(Type formatType)
  { 
     if (formatType == typeof(ICustomFormatter))
        return new StringPadder();

     return null;
  }
  public static readonly IFormatProvider Default =
     new StringPadderFormatProvider();
}

Vous pouvez alors l'utiliser comme ceci :

string.Format(StringPadderFormatProvider.Default, "->{0:x20}<-", "Hello");

0 votes

Celui-ci permet de formater plusieurs arguments. Mise à jour OP.

0 votes

Pour GetFormat devrait être (Type formatType) plutôt que (Type type), je pense.

12voto

Vous pourriez encapsuler la chaîne dans une structure qui implémente IFormattable.

public struct PaddedString : IFormattable
{
   private string value;
   public PaddedString(string value) { this.value = value; }

   public string ToString(string format, IFormatProvider formatProvider)
   { 
      //... use the format to pad value
   }

   public static explicit operator PaddedString(string value)
   {
     return new PaddedString(value);
   }
}

Ensuite, utilisez ceci comme cela :

 string.Format("->{0:x20}<-", (PaddedString)"Hello");

résultat :

"->xxxxxxxxxxxxxxxHello<-"

3voto

configurator Points 15594

Edit : J'ai mal compris votre question, je pensais que vous demandiez comment remplir les espaces.

Ce que vous demandez n'est pas possible en utilisant le string.Format composante d'alignement ; string.Format est toujours remplacée par des espaces blancs. Voir le Composant d'alignement section de MSDN : Formatage des composites .

Selon Reflector, c'est le code qui s'exécute à l'intérieur StringBuilder.AppendFormat(IFormatProvider, string, object[]) qui est appelé par string.Format :

int repeatCount = num6 - str2.Length;
if (!flag && (repeatCount > 0))
{
    this.Append(' ', repeatCount);
}
this.Append(str2);
if (flag && (repeatCount > 0))
{
    this.Append(' ', repeatCount);
}

Comme vous pouvez le constater, les blancs sont codés en dur pour être remplis d'espaces.

0 votes

C'est possible avec des chiffres Je trouverais vraiment stupide que ce soit possible avec des chiffres et pas avec des chaînes de caractères.

0 votes

Comment est-ce possible avec des chiffres ?

0 votes

J'étais un peu allongé là. Mais vous pouvez faire ce qui suit : Console.WriteLine("->{0:00000}<-", 12) ; Cela vous donnerait ->00012<-

2voto

Emax83 Points 29

Simple :

    dim input as string = "SPQR"
    dim format as string =""
    dim result as string = ""

    'pad left:
    format = "{0,-8}"
    result = String.Format(format,input)
    'result = "SPQR    "

    'pad right
    format = "{0,8}"
    result = String.Format(format,input)
    'result = "    SPQR"

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X