2009-02-12 42 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" 

 
相關問題