【问题标题】:Parse a C Output map using regex使用正则表达式解析 C 输出映射
【发布时间】:2019-07-02 14:20:12
【问题描述】:

我目前正在努力使用正则表达式解析 C Output.map 文件。 我分别处理每一行: 一行可能是这样的

__func_name     |00010d88|   T  |              FUNC|00000010|     |.text

预期输出:
1) “__func_name”
2) “00010d88”
3) “T”
4) “功能”
5) “00000010”
6)(空字符串)
7) “.text”
8) (空字符串)

但是,文本之间的空格数量会有所不同: 另一行可能如下所示:

__func_name2|0007bb7c|   T  |              FUNC|00000034|     |.text    sourcefile.c:49

1) “__func_name2” 2) “0007bb7c” 3) “T” 4)“功能” 5)“00000034” 6) (空字符串)

7) “.text”

8) "sourcefile.c:49"

正如您所见,不仅空格的数量不同,而且还列出了源文件。 现在我确实尝试使用正则表达式解决这个问题。 我的正则表达式基本上需要以下要求

  1. 字母数字字符串

  2. 一个(十六进制)数字

  3. 一个字母

  4. 一个字符串

  5. 一个(十六进制)数字

  6. 可选字符串

  7. 另一个可选字符串

每个组由| 字符分隔。 我试过这个正则表达式。虽然不完整,但 regexr 告诉我我只匹配第一组。

你能帮我弄清楚我的正则表达式有什么问题吗?

([__A-Za-z0-9])\w+|((([\|]{1})&[0-9a-h]&([\|]{1})))\w+|([A-Z])\w+

您可以在此处尝试现场演示: https://regexr.com/4gpvf

编辑:添加预期输出

【问题讨论】:

  • | 被用作分隔符似乎相当明显。将其拆分,然后修剪每个结果字符串不是更简单吗?最后一段是.text sourcefile.c:49,可以使用更简单的正则表达式轻松解析。
  • 您希望在第二个示例中得到什么输出 - 您希望源文件成为最终字符串的一部分、两个单独的字符串还是省略了源文件?
  • 你是这个意思吗? regex101.com/r/BFDygW/1
  • hm 拆分是个好主意。你的意思是这样吗? string[] single_element = single_line.Split((char)('|')); ?
  • 只是single_line.Split('|')。如果您想保留列索引,我不会删除空列。

标签: c# regex


【解决方案1】:

一个相当简单的匹配模式可能是这样的:

@"\s*(\S*)\s*\|\s*([a-f0-9]+)\s*\|\s*(\S)\s*\|\s*(\S*)\s*\|\s*([a-f0-9]+)\s*\|\s*(\S*)\s*\|\s*(\S*)\s*(\S*).*"

以这种方式执行:

  string[] data = 
  {
    "__func_name   | 00010d88 | T | FUNC | 00000010 |     |.text",
    "__func_name2 | 0007bb7c | T | FUNC | 00000034 |     |.text    sourcefile.c:49"
  };

  var matchess = data.Select(s => Regex.Matches(s, @"\s*(\S*)\s*\|\s*([a-f0-9]+)\s*\|\s*(\S)\s*\|\s*(\S*)\s*\|\s*([a-f0-9]+)\s*\|\s*(\S*)\s*\|\s*(\S*)\s*(\S*).*", RegexOptions.IgnoreCase));

  foreach (MatchCollection matches in matchess)
  {
    foreach (Match match in matches)
    {
      foreach (Group group in match.Groups)
      {
        Console.WriteLine(group.Value);
      }
    }
  }

【讨论】:

    【解决方案2】:
    static void Main()
    {
        var x = @"__func_name2|0007bb7c|   T  |              FUNC|00000034|     |.text    sourcefile.c:49";
        var matches = Regex.Split(x, @"\s*\|\s*");
        int len = matches.Length;
        int i = 0;
        for (int z = 0; z < len; ++z)
        {
            ++i;
            if (z == len - 1)
            {
                var match = Regex.Match(matches[z], @"^(?i)(?'text'\.[a-z]+)(\s+(?'file'[a-z]+\.[a-z]+:[0-9]+))?$");
                WriteLine($"{++i}) {match.Groups["text"].Value}");
                WriteLine($"{++i}) {(match.Groups["file"].Length == 0 ? "" : match.Groups["file"].Value)}");
            }
            else
            {
                WriteLine($"{z+1}) {matches[z]}");
            }
        }
    }
    
    /* Output:
        1) __func_name2
        2) 0007bb7c
        3) T
        4) FUNC
        5) 00000034
        6)
        8) .text
        9) sourcefile.c:49
    */
    

    【讨论】:

      【解决方案3】:

      正则表达式似乎是不必要的,但如果没有选项存在,这个表达式:

      (__[^\|\s]+)\s*\|([^\|\s]+)\s*\|\s*([A-Z]+)\s*\|\s*([A-Z]+)\s*\|([^\|\s]+)\s*\|\s*\|([^\|\s]+)\s*(?:([^:]+)?\s*:\s*?([0-9]+))?
      

      可能会收集我们想要的值,而忽略空格和管道,这里有一个 sourcefile 的可选组:

      (?:([^:]+)?\s*:\s*?([0-9]+))?
      

      Demo

      示例

      using System;
      using System.Text.RegularExpressions;
      
      public class Example
      {
          public static void Main()
          {
              string pattern = @"(__[^\|\s]+)\s*\|([^\|\s]+)\s*\|\s*([A-Z]+)\s*\|\s*([A-Z]+)\s*\|([^\|\s]+)\s*\|\s*\|([^\|\s]+)\s*(?:([^:]+)?\s*:\s*?([0-9]+))?";
              string input = @"__func_name2|0007bb7c|   T  |              FUNC|00000034|     |.text    sourcefile.c:49
      
      __func_name     |00010d88|   T  |              FUNC|00000010|     |.text";
              RegexOptions options = RegexOptions.Multiline;
      
              foreach (Match m in Regex.Matches(input, pattern, options))
              {
                  Console.WriteLine("'{0}' found at index {1}.", m.Value, m.Index);
              }
          }
      }
      

      【讨论】:

      • 非常好的工作。多谢 ! (我会投票给你,但看起来我没有足够的声誉)
      猜你喜欢
      • 1970-01-01
      • 2021-01-19
      • 2021-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-23
      • 2015-12-22
      相关资源
      最近更新 更多