【问题标题】:Extracting data from plain text string从纯文本字符串中提取数据
【发布时间】:2012-11-22 07:03:48
【问题描述】:

我正在尝试处理来自系统的报告,该系统为我提供以下代码

000=[GEN] OK {Q=1 M=1 B=002 I=3e5e65656-e5dd-45678-b785-a05656569e}

我需要提取大括号 {} 之间的值并将它们保存到变量中。我想我需要使用正则表达式或类似方法来做到这一点?我真的不知道从哪里开始!!我正在使用 c# asp.net 4。

我需要以下变量

param1 = 000
param2 = GEN
param3 = OK
param4 = 1 //Q
param5 = 1 //M
param6 = 002 //B
param7 = 3e5e65656-e5dd-45678-b785-a05656569e //I

我将根据参数的实际含义命名参数。任何人都可以在这里帮助我吗?我试图根据空格进行拆分,但我得到了其他垃圾!

感谢任何指点/帮助!

【问题讨论】:

  • 在“=”上拆分?会一直采用这种格式吗?
  • 你想捕捉GEN,OK 什么时候他们会一直在那里

标签: c# regex string string-matching


【解决方案1】:

如果格式相当固定,您可以使用 .NET 字符串处理方法提取值,类似于

string line = 
    "000=[GEN] OK {Q=1 M=1 B=002 I=3e5e65656-e5dd-45678-b785-a05656569e}";

int start = line.IndexOf('{');
int end = line.IndexOf('}');
string variablePart = line.Substring(start + 1, end - start);
string[] variables = variablePart.Split(' ');
foreach (string variable in variables)
{
    string[] parts = variable.Split('=');
    // parts[0] holds the variable name, parts[1] holds the value
}

这是在我脑海中写下的,所以某处可能存在一个错误。此外,建议添加错误检查,例如确保输入字符串同时具有 { 和 }。

【讨论】:

  • 虽然这是regex 的替代方案,但您仍然在让它变得复杂..regex 会以更好的方式做到这一点,而不会弄乱代码......这也会导致操作不想要的数组..他想将其存储在单个变量中..这里不推荐非正则表达式解决方案..
  • @Some1.Kill.The.DJ:也许吧。这真的取决于要求。 RegEx 通常较慢。将我的代码和 hal.stephenk 的代码放入一个简单的控制台应用程序并运行每 1,000,000 次(仅重复 objRegex.Match,而不是 new RegularExpression)显示我的代码为 1.052 秒,他的代码为 6.663 秒。有时,这种表现很重要。有时它不会。 RegEx 是一种通用的模式匹配解决方案。它的执行速度几乎永远不会像专门编写的代码那样快,尽管它可以更快地编写。
【解决方案2】:

使用正则表达式。

快速而肮脏的尝试:

(?<ID1>[0-9]*)=\[(?<GEN>[a-zA-Z]*)\] OK {Q=(?<Q>[0-9]*) M=(?<M>[0-9]*) B=(?<B>[0-9]*) I=(?<I>[a-zA-Z0-9\-]*)}

这将生成名为 ID1GENQMBI 的命名组。

查看MSDN docs 了解在 C# 中使用正则表达式的详细信息。

您可以使用Regex Hero 进行快速 C# 正则表达式测试。

【讨论】:

    【解决方案3】:

    我会建议这种类型的工作使用正则表达式。

    var objRegex = new System.Text.RegularExpressions.Regex(@"^(\d+)=\[([A-Z]+)\] ([A-Z]+) \{Q=(\d+) M=(\d+) B=(\d+) I=([a-z0-9\-]+)\}$");
    var objMatch = objRegex.Match("000=[GEN] OK {Q=1 M=1 B=002 I=3e5e65656-e5dd-45678-b785-a05656569e}");
    if (objMatch.Success)
    {
        Console.WriteLine(objMatch.Groups[1].ToString());
        Console.WriteLine(objMatch.Groups[2].ToString());
        Console.WriteLine(objMatch.Groups[3].ToString());
        Console.WriteLine(objMatch.Groups[4].ToString());
        Console.WriteLine(objMatch.Groups[5].ToString());
        Console.WriteLine(objMatch.Groups[6].ToString());
        Console.WriteLine(objMatch.Groups[7].ToString());
    }
    

    我刚刚对此进行了测试,对我来说效果很好。

    【讨论】:

      【解决方案4】:

      您可以使用String.Split

      string[] parts = s.Split(new string[] {"=[", "] ", " {Q=", " M=", " B=", " I=", "}"},
                               StringSplitOptions.None);
      

      【讨论】:

        【解决方案5】:

        此解决方案将您的报表代码分解为多个段,并将所需的值存储到一个数组中。

        正则表达式一次匹配一个报告代码段,并将适当的值存储在“Parsed Report Code Array”中。

        正如您的示例所暗示的,前两个代码段的处理方式与之后的代码段不同。我假设总是前两个段的处理方式不同。

        private static string[] ParseReportCode(string reportCode) {
            const int FIRST_VALUE_ONLY_SEGMENT = 3;
            const int GRP_SEGMENT_NAME = 1;
            const int GRP_SEGMENT_VALUE = 2;
            Regex reportCodeSegmentPattern = new Regex(@"\s*([^\}\{=\s]+)(?:=\[?([^\s\]\}]+)\]?)?");
            Match matchReportCodeSegment = reportCodeSegmentPattern.Match(reportCode);
        
            List<string> parsedCodeSegmentElements = new List<string>();
            int segmentCount = 0;
            while (matchReportCodeSegment.Success) {
                if (++segmentCount < FIRST_VALUE_ONLY_SEGMENT) {
                    string segmentName = matchReportCodeSegment.Groups[GRP_SEGMENT_NAME].Value;
                    parsedCodeSegmentElements.Add(segmentName);
                }
                string segmentValue = matchReportCodeSegment.Groups[GRP_SEGMENT_VALUE].Value;
                if (segmentValue.Length > 0) parsedCodeSegmentElements.Add(segmentValue);
                matchReportCodeSegment = matchReportCodeSegment.NextMatch();
            }
            return parsedCodeSegmentElements.ToArray();
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-06-13
          • 1970-01-01
          • 1970-01-01
          • 2012-02-25
          • 1970-01-01
          相关资源
          最近更新 更多