【问题标题】:What's the most efficient way to format the following string?格式化以下字符串的最有效方法是什么?
【发布时间】:2023-03-20 19:55:01
【问题描述】:

我有一个非常简单的问题,我不应该对此挂断电话,但我是。哈哈!

我收到了以下格式的字符串:

123

123456-D53

123455-4D

234234-4

123415

所需的输出,后格式,是:

123-455-444

123-455-55

123-455-5

123-455

格式最终取决于原始字符串中的字符总数..

我对如何做到这一点有几个想法,但我认为有比字符串更好的方法。替换和连接......

感谢您的建议..

伊恩

【问题讨论】:

  • 您确定效率是这里最重要的指标,而不是可读性?您是否分析过这是您程序中的瓶颈?
  • 两个帐户都没有。事实上,我确信这不是瓶颈,效率也不是最重要的指标。我只是好奇,整天都在想这件事。 :)

标签: c# string formatting


【解决方案1】:

Tanascius 是对的,但由于我缺乏代表,我无法发表评论或投票,但如果您想了解有关 string.format 的更多信息,我发现这很有帮助。 http://blog.stevex.net/string-formatting-in-csharp/

【讨论】:

  • 我应该让你知道我删除了我的答案:-)。 OP改变了问题,它不再适用。此外,sixlettervariable 指出它实际上也没有回答原始问题。
【解决方案2】:

我假设这不仅仅依赖于输入总是数字?如果是这样,我正在考虑这样的事情

private string ApplyCustomFormat(string input)
{
    StringBuilder builder = new StringBuilder(input.Replace("-", ""));

    int index = 3;
    while (index < builder.Length)
    {
        builder.Insert(index, "-");
        index += 4;
    }
    return builder.ToString();
}

【讨论】:

  • 这与我的实现类似。我只是想知道“这是最有效的方法吗?”问题..
  • @Ian P -- “最高效”不如“足够高效”重要。见第一条评论。我很想编写使用 IEnumerable 分块器(方法或正则表达式)和 String.Join 的“效率较低”的代码;-)
  • 选择这个作为答案,因为它首先按照我描述的规范工作。尽管如此,其他发布者也更新了他们的代码以按要求工作。都值得打绿色的勾,但我只能打一个:)
【解决方案3】:

这是一种方法,它使用正则表达式和 LINQ 的组合来一次提取三个字母的组,然后再次将它们连接在一起。注意:它假设输入已经被验证。也可以使用正则表达式进行验证。

string s = "123456-D53";
string[] groups = Regex.Matches(s, @"\w{1,3}")
                       .Cast<Match>()
                       .Select(match => match.Value)
                       .ToArray();
string result = string.Join("-", groups);

结果:

123-456-D53

【讨论】:

    【解决方案4】:

    编辑:查看旧版本的历史记录。
    您只能使用char.IsDigit() 来查找数字。

    var output = new StringBuilder();
    var digitCount = 0;
    
    foreach( var c in input )
    {
      if( char.IsDigit( c ) )
      {
        output.Append( c );
        digitCount++;
        if( digitCount % 3 == 0 )
        {
          output.Append( "-" );
        }
      }
    }
    
    // Remove possible last -
    return output.ToString().TrimEnd('-');
    

    这段代码应该从左到右填充(现在我明白了,先阅读,然后编码)...
    抱歉,我现在仍然无法测试。

    【讨论】:

    • 我要澄清一下我原来的帖子,字符串可以是字母数字,而不仅仅是数字。
    • 我认为这会以错误的方向填充数字。可以这么说,他希望它是左对齐的。
    • @Ian:我现在使用 char.IsDigit。 @sixlettervariables:你是对的,这让它变得更加困难。
    • @Ian:我的解决方案现在删除了字母......希望你想要这个,因为你的问题不清楚(所有输出都只有数字)
    • 我不在最新的 .Net 上,所以这可能已更改,但不应将 == "-" 替换为 == '-'
    【解决方案5】:

    不是最快的,但对眼睛很容易(ed: to read):

    string Normalize(string value)
    {
        if (String.IsNullOrEmpty(value)) return value;
    
        int appended = 0;
        var builder = new StringBuilder(value.Length + value.Length/3);
        for (int ii = 0; ii < value.Length; ++ii)
        {
            if (Char.IsLetterOrDigit(value[ii]))
            {
                builder.Append(value[ii]);
                if ((++appended % 3) == 0) builder.Append('-');
            }
        }
    
        return builder.ToString().TrimEnd('-');
    }
    

    使用猜测来预分配StringBuilder 的长度。这将接受任何字母数字输入以及用户添加的任何数量的垃圾,包括多余的空格。

    【讨论】:

    • 哈哈,我们的眼睛一定是不一样的:p
    • 你应该检查(ii + 1) % 3 == 0
    • @0xA3:很好的收获。 @pst:如果我回来阅读这篇文章,很明显发生了什么。没有混淆;)
    • 您更新了代码,但仍然是错误的 ;-) 所以要么检查((builder.Length+ 1) % 4) == 0 要么检查((ii + 1) % 3 == 0)
    猜你喜欢
    • 1970-01-01
    • 2011-11-13
    • 1970-01-01
    • 2010-10-25
    • 1970-01-01
    • 1970-01-01
    • 2011-03-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多