【问题标题】:Regex for finding message identifiers用于查找消息标识符的正则表达式
【发布时间】:2021-02-12 17:40:04
【问题描述】:

请一位正则表达式专家帮我解决这个问题。

这里是文中的一个例子:

BO_ 2617247491 Msg_06: 8 DataloggerConfiguration
 SG_ DL_error_active_3 : 11|8@1+ (1,0) [0|1111] "[-]" Vector__XXX
 SG_ DL_error_active_2 : 11|8@1+ (1,0) [0|1111] "[-]" Vector__XXX
 SG_ DL_error_active_1 : 11|8@1+ (1,0) [0|1111] "[-]" Vector__XXX
 SG_ DL_error_active_0 : 11|8@1+ (1,0) [0|1111] "[-]" Vector__XXX
 SG_ DL_error_code_5 : 11|8@1+ (1,0) [0|1111] "[-]" Vector__XXX
 SG_ DL_error_code_4 : 11|8@1+ (1,0) [0|1111] "[-]" Vector__XXX
 SG_ DL_error_code_3 : 11|8@1+ (1,0) [0|1111] "[-]" Vector__XXX
 SG_ DL_error_code_2 : 11|8@1+ (1,0) [0|1111] "[-]" Vector__XXX
 SG_ DL_error_code_1 : 11|8@1+ (1,0) [0|1111] "[-]" Vector__XXX
 SG_ DL_error_code_0 : 11|8@1+ (1,0) [0|1111] "[-]" Vector__XXX

BO_ 2617248003 Msg_08: 8 DataloggerConfiguration
 SG_ DL_gl_err_rea : 11|8@1+ (1,0) [0|1111] "[-]" Vector__XXX
 SG_ DL_gl_err_rea_hi : 11|8@1+ (1,0) [0|1111] "[-]" Vector__XXX

BO_ 617247747 Msg_07: 8 DataloggerConfiguration
 SG_ DL_error_code_11 : 11|8@1+ (1,0) [0|1111] "[-]" Vector__XXX
 SG_ DL_error_code_10 : 11|8@1+ (1,0) [0|1111] "[-]" Vector__XXX
 SG_ DL_error_code_6 : 11|8@1+ (1,0) [0|1111] "[-]" Vector__XXX
 SG_ DL_di_nr_of_active_entries : 11|8@1+ (1,0) [0|1111] "[-]" Vector__XXX
 SG_ DL_error_code_9 : 11|8@1+ (1,0) [0|1111] "[-]" Vector__XXX
 SG_ DL_error_code_8 : 11|8@1+ (1,0) [0|1111] "[-]" Vector__XXX
 SG_ DL_error_code_7 : 11|8@1+ (1,0) [0|1111] "[-]" Vector__XXX

我正在尝试查找那些消息标识符(10 位数字。在 BO_ 之后),在它后面的任何地方都有 DL_error_code。

据我所知是这个正则表达式:

(?<!VAL_\s)\d{10}(?=.*\n*.*DL_error_code)

【问题讨论】:

  • 您的正则表达式没有包含文本BO_的任何原因?我认为这很简单:"BO_\s+(?&lt;id&gt;\d+)\s+"
  • 或者干脆... ^BO_ (\d{10})

标签: c# .net regex


【解决方案1】:

一个选项可能是使用捕获组。

^BO_ (\d{10}).*(?:\r?\n(?!\s*BO_|.*?DL_error_code).*)*\r?\n.*?DL_error_code

模式匹配:

  • ^ 字符串开头
  • BO_ 字面匹配
  • (\d{10})组 1 中捕获 10 位数字
  • .* 匹配该行的其余部分
  • (?:非捕获组整体重复
    • \r?\n 匹配换行符
    • (?!\s*BO_|.*?DL_error_code).* 如果不以BO_ 开头或包含DL_error_code,则匹配整行
  • )* 关闭群组并可选择重复
  • \r?\n.*?DL_error_code匹配包含DL_error_code的行

Regex demo | C# demo

注意第二项有9位617247747

如果你想匹配all the digits,你也可以使用\d+而不是\d{10},它会匹配1个或多个数字。

string pattern = @"^BO_ (\d{10}).*(?:\r?\n(?!\s*BO_|.*?DL_error_code).*)*\r?\n.*?DL_error_code";
string input = @"...";

foreach (Match m in Regex.Matches(input, pattern, options))
{
    Console.WriteLine(m.Groups[1].Value);
}

输出

2617247491

【讨论】:

    【解决方案2】:

    我解析文本文件已有 40 多年了。可以使用时应使用字符串方法,而当字符串方法不起作用时应使用正则表达式。正则表达式并不总是最好的答案。请参阅下面的代码:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.IO;
    using System.Text.RegularExpressions;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            const string FILENAME = @"c:\temp\test.txt";
            static void Main(string[] args)
            {
                StreamReader reader = new StreamReader(FILENAME);
    
                string line = "";
                List<BO> bos = new List<BO>();
                BO bo = null;
                string[] splitLine = null;
                while ((line = reader.ReadLine()) != null)
                {
                    line = line.Trim();
                    if (line.Length > 0)
                    {
                        if (line.StartsWith("BO"))
                        {
                            bo = new BO();
                            bos.Add(bo);
                            splitLine = line.Split(new char[] { ' ' }).ToArray();
                            bo.number = splitLine[1];
                        }
                        else
                        {
                            if (line.Contains("DL_error_code"))
                            {
                                splitLine = line.Split(new char[] { ':' }).ToArray();
                                if (bo.de_error_codes == null) bo.de_error_codes = new List<string>();
                                bo.de_error_codes.Add(splitLine[1].Trim());
                            }
                        }
                    }
                }
            }
        }
        public class BO
        {
            public string number { get; set; }
            public List<string> de_error_codes { get; set; }
        }
    }
    

    【讨论】:

    • 谢谢,我也试试这个。这是一个有趣的解决方案。
    猜你喜欢
    • 2011-12-19
    • 2013-10-19
    • 2013-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多