格式化字母数字字符串

时间:2010-02-18 07:55:54

标签: c# string formatting

我有一个包含16个字母数字字符的字符串,例如F4194E7CC775F003。我想把它格式化为F419-4E7C-C775-F003。

我尝试使用

string.Format("{0:####-####-####-####}","F4194E7CC775F003");

但这不起作用,因为它不是数值。

所以我想出了以下内容:

public class DashFormatter : IFormatProvider, ICustomFormatter
{
  public object GetFormat(Type formatType)
  {
    return this;
  }

  public string Format(string format, object arg, IFormatProvider formatProvider)
  {
    char[] chars = arg.ToString().ToCharArray();
    StringBuilder sb = new StringBuilder();

    for (int i = 0; i < chars.Length; i++)
    {
      if (i > 0 && i % 4 == 0)
      {
        sb.Append('-');
      }

      sb.Append(chars[i]);
    }

    return sb.ToString();
  }
}

并使用

string.Format(new DashFormatter(), "{0}", "F4194E7CC775F003");

我能够解决问题,但我希望有更好/更简单的方法吗?也许是一些LINQ魔术?

感谢。

7 个答案:

答案 0 :(得分:8)

如果没有Linq,你可以在一行中完成:

        StringBuilder  splitMe = new StringBuilder("F4194E7CC775F003");
        string joined = splitMe.Insert(12, "-").Insert(8, "-").Insert(4, "-").ToString();

答案 1 :(得分:2)

你可以使用正则表达式来完成,但我不知道将其性能与其他方法相比较。

string formattedString = Regex.Replace(yourString, "(\\S{4})\\B", "$1-");

如果你想这样做,你可以将它放在字符串的扩展方法中:

yourString.ToDashedFormat();

答案 2 :(得分:1)

如果你想要它linq:

var formatted = string.Join("-", Enumerable.Range(0,4).Select(i=>s.Substring(i*4,4)).ToArray());

如果你想要它有效:

var sb = new StringBuilder(19);
sb.Append(s,0,4);
for(var i = 1; i < 4; i++ )
{
 sb.Append('-');
 sb.Append(s,i*4, 4);
}
return sb.ToString();

我没有对此进行基准测试,但我认为它会比StringBuilder.Insert更快,因为它不会多次移动字符串的其余部分,它只会写入4个字符。 此外,它不会重新分配底层字符串,因为它在开始时预分配为19个字符。

答案 3 :(得分:1)

基于Carra's answer我制作了这个小实用方法:

private static string ToDelimitedString(string input, int position, string delimiter)
{
  StringBuilder sb = new StringBuilder(input);

  int x = input.Length / position;

  while (--x > 0)
  {
    sb = sb.Insert(x * position, delimiter);
  }

  return sb.ToString();
}

你可以像这样使用它:

string result = ToDelimitedString("F4194E7CC775F003", 4, "-");

一个测试用例:

[Test]
public void ReturnsDelimitedString()
{
  string input = "F4194E7CC775F003";

  string actual = ToDelimitedString(input, 4, "-");

  Assert.AreEqual("F419-4E7C-C775-F003", actual);
}

答案 4 :(得分:0)

 char[] chars = "F4194E7CC775F003".ToCharArray();
            var str = string.Format("{0}-{1}-{2}-{3}"
                                  , new string(chars.Take(4).ToArray())
                                  , new string(chars.Skip(4).Take(4).ToArray())
                                  , new string(chars.Skip(8).Take(4).ToArray())
                                  , new string(chars.Skip(12).Take(4).ToArray())  
                );

答案 5 :(得分:0)

我能想到的最简单的解决方案是

        var text = "F4194E7CC775F003";
        var formattedText = string.Format(
            "{0}-{1}-{2}-{3}",
            text.Substring(0, 4),
            text.Substring(4, 4),
            text.Substring(8, 4),
            text.Substring(12, 4));

答案 6 :(得分:0)

仅9年后,与Carra的回答略有不同。根据我的测试,速度提高了约2.5倍(将所有“-”更改为“-”):

        StringBuilder initial = new StringBuilder("F4194E7CC775F003");
        return initial.Insert(12, '-').Insert(8, '-').Insert(4, '-').ToString();