有没有办法更好地解析字符串?

Sar*_*ley 38 .net c# string parsing

我想知道在.NET中是否有内置的方法来解析字符串的位.

以我为例,我有以下字符串:

"bsarbirthd0692"
Run Code Online (Sandbox Code Playgroud)

由以下部分组成,以后将与数据交叉引用:

Indexes   Purpose
0-3       (name)
4-9       (description)
10-13     (date mm-yy)
Run Code Online (Sandbox Code Playgroud)

我希望有一些原生的东西:

string name, desc, date;
string.ParseFormat("{0:4}{1:5}{2:4}", "bsarbirthd0692", out name, out desc, out date);
Run Code Online (Sandbox Code Playgroud)

在.NET或流行的库中是否有以本机方式执行此操作?

Sha*_*r80 50

由于格式已知,因此不应更改Substring应该适合您

string data = "bsarbirthd0692";
string name, desc, date;
name = data.Substring(0, 4);
desc = data.Substring(4, 6);
date = data.SubString(10);
Run Code Online (Sandbox Code Playgroud)

编辑

您还可以创建扩展方法来执行您想要的任何操作.这显然比以前的建议更复杂

public static class StringExtension
{
    /// <summary>
    /// Returns a string array of the original string broken apart by the parameters
    /// </summary>
    /// <param name="str">The original string</param>
    /// <param name="obj">Integer array of how long each broken piece will be</param>
    /// <returns>A string array of the original string broken apart</returns>
    public static string[] ParseFormat(this string str, params int[] obj)
    {
        int startIndex = 0;
        string[] pieces = new string[obj.Length];
        for (int i = 0; i < obj.Length; i++)
        {
            if (startIndex + obj[i] < str.Length)
            {
                pieces[i] = str.Substring(startIndex, obj[i]);
                startIndex += obj[i];
            }
            else if (startIndex + obj[i] >= str.Length && startIndex < str.Length)
            {
                // Parse the remaining characters of the string
                pieces[i] = str.Substring(startIndex);
                startIndex += str.Length + startIndex;
            }

            // Remaining indexes, in pieces if they're are any, will be null
        }

        return pieces;
    }
}
Run Code Online (Sandbox Code Playgroud)

用法1:

string d = "bsarbirthd0692";
string[] pieces = d.ParseFormat(4,6,4);
Run Code Online (Sandbox Code Playgroud)

结果:

在此输入图像描述

用法2:

string d = "bsarbirthd0692";
string[] pieces = d.ParseFormat(4,6,4,1,2,3);
Run Code Online (Sandbox Code Playgroud)

结果:

在此输入图像描述

  • Upvoted:保持代码简单易懂. (5认同)
  • _"格式已知,不应更改"_即使已知格式可能会更改.例如,如果数据不在您的控制之下.但在使用之前添加"长度"检查很容易. (3认同)

Ili*_*kov 16

您可以使用Regexp

string str= "bsarbirthd0692";
var regex = "(?<name>.{4})(?<desc>.{6})(?<date>.{4})";
MatchCollection matches = Regex.Matches(str, regex);
foreach(Match m in matches){
    Console.WriteLine(m.Groups["name"].ToString());
    Console.WriteLine(m.Groups["desc"].ToString());
    Console.WriteLine(m.Groups["date"].ToString());
}
Run Code Online (Sandbox Code Playgroud)

  • @mellamokb正则表达式是一个很棒的锤子.只要确保你只在指甲上使用它们:D (5认同)
  • 正则表达式在这里是过度的(而OP显然是一个正则表达式的处女,不需要额外的混乱).但是,使用命名组的道具可以避免对新手完全不理解. (5认同)
  • @Luaan正如我的同事曾经告诉我的那样,"短语"不要用锤子来驱动螺丝"并不意味着你可以用扳手来敲打它们." (2认同)

Ric*_*ard 11

没有类似的东西,但是要写一些东西来实现:

IEnumerable<string> inputString.BreakIntoLengths(4, 6, 4)
Run Code Online (Sandbox Code Playgroud)

签名:

public IEnumerable<string> BreakIntoLengths(this string input, params int[] lengths);
Run Code Online (Sandbox Code Playgroud)

很容易:

public IEnumerable<string> BreakIntoLengths(this string input, params int[] lengths) {

  var pos = 0;
  foreach (var len in lengths) {
    yield return input.Substring(pos, len);
    pos += len;
  }
}
Run Code Online (Sandbox Code Playgroud)

(实际的实现有一些错误检查.)

NB.我已经删除了类似接口的格式字符串:它似乎没有提供任何价值.返回集合后,很容易按索引分配条目.