【问题标题】:Format string with dashes用破折号格式化字符串
【发布时间】:2010-10-19 13:28:38
【问题描述】:

我有一个从导入文件中提取的压缩字符串值。我需要将其格式化为包裹号,其格式如下:##-##-##-###-###。因此,字符串“410151000640”应该变成“41-01-51-000-640”。我可以用以下代码做到这一点:

String.Format("{0:##-##-##-###-###}", Convert.ToInt64("410151000640"));

但是,字符串可能不是全是数字;它可能有一个或两个字母,因此转换为 int 将失败。有没有办法在字符串上执行此操作,以便每个字符(无论是数字还是字母)都能正确适应格式?

【问题讨论】:

    标签: c# .net string.format


    【解决方案1】:
    Regex.Replace("410151000640", @"^(.{2})(.{2})(.{2})(.{3})(.{3})$", "$1-$2-$3-$4-$5");
    

    或者稍微短一点的版本

    Regex.Replace("410151000640", @"^(..)(..)(..)(...)(...)$", "$1-$2-$3-$4-$5");
    

    【讨论】:

    • 像魅力一样工作!我将它提取到一个带有一些验证和错误处理的包装方法中。谢谢!
    • 我自己必须真正正确地学习正则表达式。这个问题的一个很好的解决方案。
    • @Øyvind 如果有帮助,我喜欢使用regular-expressions.info/tutorial.html 作为参考。他们还讨论了不同引擎提供的不同风格的正则表达式。
    • 谢谢。我会在那里阅读RegExp。看起来是一个很好的信息来源。
    【解决方案2】:

    只要您知道“包裹编号”始终符合特定规则,我会通过您自己的格式化方法来解决此问题。

    public static string FormatParcelNumber(string input)
    {
      if(input.length != 12)
         throw new FormatException("Invalid parcel number. Must be 12 characters");
    
      return String.Format("{0}-{1}-{2}-{3}-{4}",
                    input.Substring(0,2),
                    input.Substring(2,2),
                    input.Substring(4,2), 
                    input.Substring(6,3), 
                    input.Substring(9,3));
    }
    

    【讨论】:

    • 这很好用。所以真正归结为是否使用正则表达式(我不是专家)。
    【解决方案3】:

    这应该适用于您的情况:

    string value = "410151000640";
    for( int i = 2; i < value.Length; i+=3){
      value = value.Insert( i, "-");
    }
    

    现在value 包含插入破折号的字符串。

    编辑

    我刚刚看到你在所有的第二个数字之间没有破折号,为此需要进行一些小调整(恐怕也会让它变得更笨拙)

    string value = "410151000640";
    for( int i = 2; i < value.Length-1; i+=3){
      if( value.Count( c => c == '-') >= 3) i++;
      value = value.Insert( i, "-");
    }
    

    【讨论】:

      【解决方案4】:

      如果它是 UI 的一部分,您可以在 System.ComponentModel 中使用 MaskedTextProvider

          MaskedTextProvider prov = new MaskedTextProvider("aa-aa-aa-aaa-aaa");
          prov.Set("41x151000a40");
          string result = prov.ToDisplayString();
      

      【讨论】:

      【解决方案5】:

      这是一个带有一些实用程序的简单扩展方法:

          public static string WithMask(this string s, string mask)
          {
              var slen = Math.Min(s.Length, mask.Length);
              var charArray = new char[mask.Length];
              var sPos = s.Length - 1;
              for (var i = mask.Length - 1; i >= 0 && sPos >= 0;)
                  if (mask[i] == '#') charArray[i--] = s[sPos--];
                  else
                      charArray[i] = mask[i--];
              return new string(charArray);
          }
      

      如下使用:

              var s = "276000017812008";
              var mask = "###-##-##-##-###-###";
              var dashedS = s.WithMask(mask);
      

      您可以将它与任何字符串一起使用,并且将插入掩码中除 # 以外的任何字符。面具将从右到左工作。如果需要,您可以将其调整为另一种方式。

      玩得开心。

      【讨论】:

        【解决方案6】:

        如果我理解正确,您正在寻找一个从字符串中删除所有字母的函数,不是吗?

        我是动态创建的,如果你正在寻找它,也许你可以将它转换成 c#:

        Dim str As String = "410151000vb640"
        str = String.Format("{0:##-##-##-###-###}", Convert.ToInt64(MakeNumber(str)))
        
        
        Public Function MakeNumber(ByVal stringInt As String) As String
            Dim sb As New System.Text.StringBuilder
            For i As Int32 = 0 To stringInt.Length - 1
                If Char.IsDigit(stringInt(i)) Then
                    sb.Append(stringInt(i))
                End If
            Next
            Return sb.ToString
        End Function
        

        【讨论】:

        • 不,字母也包含在包裹号中,例如“410151000vb6”应该变成“41-01-51-000-vb6”
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-20
        • 1970-01-01
        相关资源
        最近更新 更多