【问题标题】:How to pad right with zeros using string.format while using dynamic formats?如何在使用动态格式时使用 string.format 用零填充?
【发布时间】:2015-04-29 07:09:47
【问题描述】:

我有下面的说明性代码。我需要将条件 1 的输出右对齐并用 |1234500000| 之类的零填充而不是 |0000012345|而不是固定宽度为 10。格式字符串是有条件的,这意味着根据某些标准可以有许多可能的格式字符串之一,而只有一行用于输出。因此,像 PadRight 和 PadLeft 这样的函数不能与值一起使用,除非有一种方法可以使用它们同时仍然具有相同的输出线。 (.NET 4.5)

我怎样才能得到 |1234500000|同时满足这些要求?

string format;

if (condition1)
format = "|{0:0000000000}|";
else
if (condition2)
format = "|{0}|";
//more conditions here
Int64 value = 12345;
string a = String.Format(format, value);
a.Dump();

【问题讨论】:

  • 当你用零填充它们时,你怎么知道最后一组数字中的任何一个是否应该为 0?对我来说似乎是个坏主意。
  • 什么意思?零是左对齐的,因此数字从第一个非零数字开始。数字不以零开头。
  • @Tony_Henrich:如果你真的想用零填充一个数字而不是其他的,那么你的代码工作得很好。还有哪些其他格式会使您的代码无法使用?
  • @Cᴏʀʏ 这是对某人的编辑的编辑,这改变了问题。它已被还原。

标签: c# .net string.format


【解决方案1】:

只有这么多的内置和可定制的字符串格式。也许您可以为每个条件设置不同的格式化函数,然后再调用它:

Func<Int64, String> formatter;
if (condition1) 
{
    formatter = (number) => number.ToString().PadRight(10, '0');
}
else if (condition2) 
{
    formatter = (number) => number.ToString();
}

Int64 sample = 12345;
string output = string.Format("|{0}|", formatter(sample));
output.Dump();

另一种选择是通过实现IFormatProviderICustomFormatter 创建您自己的自定义字符串格式提供程序。例如,这是一个马虎的,可以做正确的填充:

public class RightPaddedStringFormatter : IFormatProvider, ICustomFormatter
{
    private int _width;

    public RightPaddedStringFormatter(int width) 
    {
        if (width < 0)
            throw new ArgumentOutOfRangeException("width");

        _width = width;
    }

    public string Format(string format, object arg, IFormatProvider formatProvider)
    {
        // format doubles to 3 decimal places
        return arg.ToString().PadRight(_width, '0');
    }

    public object GetFormat(Type formatType)
    {
        return (formatType == typeof(ICustomFormatter)) ? this : null;
    }
}

然后您可以使用您的条件来选择格式化程序,例如:

IFormatProvider provider;
if (condition1)
{
    provider = new RightPaddedStringFormatter(10);
}
...

Int64 sample = 12345;
string output = string.Format(provider, "|{0}|", sample);
output.Dump();

【讨论】:

    【解决方案2】:

    我从上面的Possible Duplicate 复制,它看起来类似于 Cory 的答案。这允许您使用任何字符进行 string.Format 和填充,无论是 0 还是 X,它都留给格式化程序。

    写于LinqPad

    void Main()
    {
        var val = 12345;
        string.Format(new PaddedStringFormatInfo(), "{0:20:0}", val).Dump();
        string.Format(new PaddedStringFormatInfo(), "{0:-20:0}", val).Dump();
    }
    
    public sealed class PaddedStringFormatInfo : IFormatProvider, ICustomFormatter
    {
        public object GetFormat(Type formatType)
        {
            if (typeof(ICustomFormatter).Equals(formatType)) return this;
    
            return null;
        }
    
        public string Format(string format, object arg, IFormatProvider formatProvider)
        {
            if (arg == null) throw new ArgumentNullException("Argument cannot be null");
            if (format == null) return arg.ToString();
    
            string[] args = format.Split(':');
            if (args.Length == 1) String.Format("{0, " + format + "}", arg);
    
            int padLength = 0;
            if (!int.TryParse(args[0], out padLength)) throw new ArgumentException("Padding length should be an integer");
    
            switch (args.Length)
            {
                case 2: // padded format
                    if (padLength > 0)  return (arg.ToString()).PadLeft(padLength, args[1][0]);
    
                    return (arg.ToString()).PadRight(padLength * -1, args[1][0]);
    
                default: // use default string.format
                    return string.Format("{0," + format + "}", arg);
            }
        }
    }
    

    输出将是:

    00000000000000012345
    12345000000000000000
    

    【讨论】:

      猜你喜欢
      • 2011-07-09
      • 1970-01-01
      • 2015-05-19
      • 1970-01-01
      • 2017-04-07
      • 2020-09-16
      • 2018-07-03
      • 2015-10-24
      • 1970-01-01
      相关资源
      最近更新 更多