【问题标题】:Formatting a string of numbers depedning on length根据长度格式化一串数字
【发布时间】:2021-05-13 09:46:02
【问题描述】:

在我的模型中,我有一个 cNumber 字符串,它可以是不同的长度(16,24 和 28),我需要在表格中的视图中对其进行相应的格式化。

  16 length: ########-########
  24 : ########-########-########
  28 : #### #### #### #### #### #### ####

更新:我确实有一种格式化方法,但我很难将它传递给视图以显示在表的正确记录中。

        static string Format(string cNumber)
        {
            
            if (cNumber.Length == 16 || cNumber.Length == 24)
            {
                cNumber= Regex.Replace(cNumber, ".{8}", "$0-");
            }
            else if (cNumber.Length == 28)
            {
                cNumber= Regex.Replace(cNumber, ".{4}", "$0 ");
            }
            else
            {
                return cNumber;
            }

            cNumber= cNumber.Remove(cNumber.Length - 1);

            return cNumber;
        }

        
        public ActionResult Index(Guid id)
        {
            var PartnerCNumbers = db.PartnerCNumbers.Include(p => p.Partner).Where(p=>p.Partner.PartnerGuid == id);

            

            var cNumList = new List<string>();

            foreach (var cn in PartnerCNumbers)
            {
                cNumList.Add(Format(cn.cNumber));
            }

            
            ViewData["cNumbers"] = cNumList;
            ViewBag.PartnerGuid = id;
         

            return View(PartnerCNumbers.ToList());
        }

在我看来,我将 ViewData 作为列表

@model IEnumerable<Models.PartnerCNumbers>

IEnumerable<string> cNumbers= ViewData["cNumbers"] as IEnumerable<string>;

@foreach (var item in Model)
        {
            //int cLength = item.cNumber.Length;

            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.Currency)
                </td>
                <td>
                    //@Html.DisplayFor(modelItem => item.cNumber)
                    //THIS IS WHERE I NEED THE FORMATTED cNUMBER
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.sCode)
                </td>
            </tr>
}

最好的方法是什么?我在视图本身中尝试了 String.Format(),但我无法转换它,因为它已经作为字符串存储在数据库中。 例如,ViewModel 可以根据长度属性具有不同的注释吗?或者用javascript有可能吗

【问题讨论】:

    标签: javascript c# asp.net-mvc razor


    【解决方案1】:

    我会为这种类型的“自定义 ToString”创建一个扩展方法

    public static class CNumberExtensions
    {
        static string ToFormattedCNumber(this string cNumber)
        {
            switch (cNumber.Length)
            {
                case 16:
                    return cNumber.Substring(0, 8) + "-"
                         + cNumber.Substring(8);
                case 24:
                    return cNumber.Substring(0, 8) + "-"
                         + cNumber.Substring(8, 8) + "-"
                         + cNumber.Substring(16);
                case 28:
                    return cNumber.Substring(0, 4) + " "
                         + cNumber.Substring(4, 4) + " "
                         + cNumber.Substring(8, 4) + " "
                         + cNumber.Substring(12, 4) + " "
                         + cNumber.Substring(16, 4) + " "
                         + cNumber.Substring(20, 4) + " "
                         + cNumber.Substring(24);
            }
            throw new ArgumentException("cNumber length can only be 16, 24 or 28", nameof(cNumber));
        }
    }
    

    除非您每秒调用该函数数千次,否则“最快的方式”不一定是最好的。

    【讨论】:

      【解决方案2】:

      您可以根据需要在 C# 中使用以下帮助函数按长度格式化输入字符串:

      class Program
      {
          static string formatByLength(string s)
          {
              if (s.Length == 16)
              {
                  return s.Substring(0, 8) + "-" + s.Substring(8);
              }
              if (s.Length == 24)
              {
                  return s.Substring(0, 8) + "-" + s.Substring(8, 8) + "-" + s.Substring(16);
              }
              if (s.Length == 28)
              {
                  var sb = new System.Text.StringBuilder();
                  for (var i = 0; i < 7; i++)
                  {
                      if (sb.Length > 0)
                      {
                          sb.Append(" ");
                      }
                      sb.Append(s.Substring(i * 4, 4));
                  }
                  return sb.ToString();
              }
      
              // return original string
              return s;
          }
      
          static void Main(string[] args)
          {
              Console.WriteLine(formatByLength("1234567890123456"));
              Console.WriteLine(formatByLength("123456789012345678901234"));
              Console.WriteLine(formatByLength("1234567890123456789012345678"));
          }
      }
      

      输出如下结果:

      12345678-90123456
      12345678-90123456-78901234
      1234 5678 9012 3456 7890 1234 5678
      

      【讨论】:

        【解决方案3】:

        我会构建一个方法来获取具有 n 个固定长度段的字符串长度,然后在以下之间插入分隔符:

        private static string FormatNumberString(string input, int segmentLength, char delimiter)
        {
            StringBuilder builder = new StringBuilder();
            // In a 16-length string, i will initially be 0, and then on the next
            // iteration of the loop it will be 8
            for (int i = 0; i < input.Length; i += segmentLength)
            {
                // if we're just starting another block we should add the delimiter
                if (i != 0)
                {
                    builder.Append(delimiter);
                }
        
                // add the section from i to i + segmentLength (e.g. 0-7 and then 8-15)
                builder.Append(input.Substring(i, segmentLength));
            }
            return builder.ToString();
        }
        

        然后我们可以创建一种方法来更容易地调用它:

        private static string FormatNumberStringByLength(string input)
        {
            switch (input.Length)
            {
                // given the method above, 16 and 24-length strings have the same
                // run length and delimiter, so we can group these together
                case 16:
                case 24:
                    return FormatNumberString(input, 8, '-');
                case 28:
                    return FormatNumberString(input, 4, ' ');
                default:
                    throw new ArgumentException("Input string length not recognized.", nameof(input));
            }
        }
        

        用法:

        Console.WriteLine(FormatNumberStringByLength("1234567812345678"));
        Console.WriteLine(FormatNumberStringByLength("123456781234567812345678"));
        Console.WriteLine(FormatNumberStringByLength("1234123412341234123412341234"));
        

        Try it online

        【讨论】:

          【解决方案4】:

          您应该在 foreach 循环中使用 cNumbers 而不是 Model。

          IEnumerable<string> cNumbers= ViewData["cNumbers"] as IEnumerable<string>;
          
          @foreach (var cNumber in cNumbers)
          {
                      <tr>
                          <td>
                              //other model data
                          </td>
                          <td>
                             @cNumber
                          </td>
                          <td>
                              //other model data
                          </td>
                      </tr>
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2017-12-04
            • 2014-03-08
            • 1970-01-01
            • 1970-01-01
            • 2020-10-26
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多