2009-02-12 3 views
55

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

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 parce que je veux être en mesure de construire la chaîne de format à un endroit/heure différent, puis le formatage est réellement exécuté.

--EDIT--
Vu qu'il ne semble pas être une solution existante à mon problème, je suis venu avec ce (après Think Before Coding's suggestion)
--EDIT2--
je avais besoin certains scénarios plus complexes, donc je suis allé pour Think Before Coding's second suggestion

[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); 
} 

Parce que le code a été un peu trop à mettre dans un poste, je me suis déplacé à github comme essentiel: http://gist.github.com/533905#file_padded_string_format_info

Là les gens peuvent facilement se ramifier et tout :)

+0

I pense que vous devriez vous assurer que la chaîne n'est pas vide. Souhaitez-vous passer le test: chaîne.Fomat ("{0}", (PaddedString) "Bonjour"); ? – configurator

Répondre

30

Il y a une autre solution.

Mettre en œuvre IFormatProvider pour retourner un ICustomFormatter qui sera passé à 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(); 
} 

Ensuite, vous pouvez l'utiliser comme ceci:

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

Celui-ci permet le formatage de plusieurs arguments. OP mis à jour. –

+0

Le paramètre pour GetFormat doit être (Type formatType) plutôt que (type Type) je pense. – demokritos

2

Edit: j'ai mal compris votre question, je croyais que vous demandiez comment pad avec des espaces.

Ce que vous demandez n'est pas possible en utilisant le composant d'alignement string.Format; string.Format toujours des tampons avec des espaces. Voir la section Alignment Component de MSDN: Composite Formatting.

Selon réflecteur, c'est le code qui fonctionne à 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 voir, les blancs sont codés en dur à remplir des espaces.

+0

J'ai mal compris la question ... – configurator

+0

C'est possible avec des nombres .. Je dirais que c'est vraiment stupide si c'est possible avec des nombres et non avec des cordes. –

+0

Comment est-ce possible avec les nombres? – configurator

11

Vous pouvez résumer la chaîne dans une struct 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 ce comme ça:

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

Résultat:

"->xxxxxxxxxxxxxxxHello<-" 
3

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" 

 
Questions connexes