2009-02-12 38 views
55

可以使用String.Format()填充任意字符的某个字符串吗?使用string.format(不是padleft或padright)向左或向右填充任意字符串

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

returns 

->    hello<- 
->hello    <- 

我现在想要空格为任意字符。 我不能用padLeft或padRight做到这一点的原因是因为我想能够在不同的地点/时间构造格式字符串,然后实际执行格式。

- 编辑 -
看出,似乎没有被现有的解决我的问题,我想出了这个(Think Before Coding's suggestion后)
--EDIT2--
我需要一些更复杂的情况,所以我去了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); 
} 

因为代码是有点过分投入在后,我把它移到GitHub上的要点是:
http://gist.github.com/533905#file_padded_string_format_info

那里的人可以很容易地分支它和任何:)

+0

我认为你应该确保字符串不是空的。它会通过测试: 字符串。Fomat(“{0}”,(PaddedString)“Hello”); ? – configurator 2009-02-12 14:15:07

回答

30

还有另一种解决方案。

实施IFormatProvider返回一个ICustomFormatter将被传递到的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(); 
} 

然后你可以使用它像这样:

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

编辑:我误解你的问题,我还以为你问如何垫的空间。

使用string.Format对齐组件时,您所要求的是不可能的; string.Format始终填充空格。请参阅对齐组件部分MSDN: Composite Formatting

根据反射,这是内部StringBuilder.AppendFormat(IFormatProvider, string, object[])运行的代码是由string.Format称为:

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

正如你所看到的,空白硬编码来填充空白。

+0

我误解了这个问题...... – configurator 2009-02-12 13:12:19

+0

这是可能的数字..我认为它真的很愚蠢,如果它可能与数字而不是字符串。 – 2009-02-12 13:13:51

11

您可以封装在实现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); 
    } 
} 

然后用这个像这样的结构中的字符串:

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

结果:

"->xxxxxxxxxxxxxxxHello<-" 
3

简单:

 


    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" 

 
相关问题