【问题标题】:How can i extract the info between " " ? C#如何提取“”之间的信息? C#
【发布时间】:2012-06-29 10:20:31
【问题描述】:

谁能告诉我如何从这个输出中以一种简单的方式将以下信息提取到一个变量中。

输出:

AT+CMGL="ALL"
+CMGL: 0,"REC READ","+40728072005",,"12/06/29,13:04:26+12"
password,1,ON

我想从上面的输出中提取一些信息,如下所示:

msisdn="+40728072005"
passwd="password"
itemno="1"
command="ON"

--

    string split = ",";
    string[] substrings = Regex.Split(buff, split);
    foreach (string match in substrings)
    {
        Console.WriteLine("'{0}'", match);
    }

图像-> [1]:http://i.stack.imgur.com/zl6Nj.png

有没有办法从一开始就排除不需要的输出? 就像 grep -v,我对 C# 不是很熟悉。

到目前为止,我已经到了这一点:

    string split = ",";
    string split1 = "\"";
    string split2 = "OK";
    string[] substrings = Regex.Split(buff, split);
    string[] substrings1 = Regex.Split(substrings[2], split1);
    Console.WriteLine(substrings1[1]);
    string[] substrings2 = Regex.Split(substrings[5], split1);

    Console.WriteLine(substrings2[1]);
    Console.WriteLine(substrings[6]);
    string[] substrings3 = Regex.Split(substrings[7], split2);
    Console.WriteLine(substrings3[0]);

不过,这是通过拆分字符串来完成的,因为我知道消息格式。

【问题讨论】:

  • 您可以寻找现有的 CSV 解析器。框架本身不包含一个,但我敢肯定有很多开源的。
  • 我尝试了正则表达式,但没有成功。拆分文本并仅检索我需要的数据是一种更简单的方法吗?
  • 查看正则表达式教程 - 例如:msdn.microsoft.com/en-us/library/ms228595%28v=vs.100%29.aspx
  • 取决于您如何定义“更简单的方式”。在代码中,没有比单个正则表达式更简单的方法了。然而,在大脑中......显示您尝试过但没有成功的正则表达式。

标签: c# serial-port buffer


【解决方案1】:

看起来您有固定数量的逗号分隔值,因此位置定义了特定值的含义。我会删除等号之前的所有内容,然后用逗号分隔并分别处理所需的值。

【讨论】:

    【解决方案2】:

    试试这个演示,把它放在控制台应用程序的 Main 方法中(它使用正则表达式,所以你必须添加行“使用 System.Text.RegularExpressions;”):

            string input = "AT+CMGL=\"ALL\"\n+CMGL: 0,\"REC READ\",\"+40728072005\",,\"12/06/29,13:04:26+12\"\npassword,1,ON";
            var matches = Regex.Matches(
                input,
                @"\""(?<msisdn>\+\d*)\"",.*,\""(?<date>\d{2}\/\d{2}/\d{2},\d{2}:\d{2}:\d{2}\+\d{2})\"".*\n+(?<passwd>[^,]*),(?<itemno>\d*),(?<command>\w*)"
                , RegexOptions.Multiline);
    
            foreach (Match m in matches)
            {
                Console.WriteLine(m.Groups["msisdn"].Value);
                Console.WriteLine(m.Groups["date"].Value);
                Console.WriteLine(m.Groups["passwd"].Value);
                Console.WriteLine(m.Groups["itemno"].Value);
                Console.WriteLine(m.Groups["command"].Value);
            }
            Console.ReadKey();
    

    基本上,正则表达式在文本中搜索定义的模式。 表达的意思:

    \"" - 这就是引号符号的定义方式,它用反斜杠转义并写入两次,因此不会导致编译器错误。

    (?+\d*) - 通常,括号中的表达式表示您正在捕获一个组,这是一个命名组,它的名称由 ? 指定,该组将捕获以 + 符号开头的字符串 (它由反斜杠转义)后跟由反斜杠和字母“d”表示的数字(“d”来自“digit”)。反斜杠用作具有特殊含义的字符的转义字符。星号 * 表示在它之前出现的字符可以出现 0 次或更多次。

    \"" - 引号,这是“msisdn”号码的结束引号。

    , - 表示逗号。

    .* - 点表示任意字符,星号表示任意字符可以出现 0 次或多次。

    (?\d{2}/\d{2}/\d{2},\d{2}:\d{2}:\d{2}+\d{2}) - 命名组捕获日期,表达式 \d{2} 有 \d 表示数字和 {2} 告诉正则表达式引擎数字应该出现两次,然后是 / - 它表示正斜杠(它被反斜杠转义)。然后是用冒号分隔的数字,最后是加号和后面的两个数字,这就是提取日期的方式。

    \n+ - \n 表示换行符,+ 是量词,表示换行符出现一次或多次。

    (?[^,]*) - 是捕获密码部分的命名组,[^,] 表示应捕获除逗号以外的任何字符,方括号表示字符范围,^ 表示否定,星号表示该字符可以出现 0 次或更多次。

    (?\d*) - 是一个命名组,它捕获由 \d* 定义的数字

    (?\w*) - 是一个命名组,用于捕获单词字符(字母、数字和下划线)

    【讨论】:

    • 你好,它返回 5 个空行,输出还包含一些空行,最后是 OK,就像这里:i.stack.imgur.com/zl6Nj.png
    • 你好,我改了,你现在可以试试
    • 我很高兴为您提供帮助,它是否为您提供了所需的输出?我还将 Singleline 更改为 Multiline 模式,以便它返回这种模式的所有出现(不仅仅是找到的第一个)。
    • Ivan 你能帮我用另一个正则表达式,或者更好地解释一下这个是如何完成的,以便我可以修改它并制作另一个:D。
    • 当然,我会在答案中添加更多 cmets。最好的办法是阅读有关正则表达式的教程之一
    猜你喜欢
    • 2019-11-15
    • 2021-01-11
    • 2017-06-04
    • 2012-07-03
    • 1970-01-01
    • 1970-01-01
    • 2019-08-31
    • 2021-02-06
    • 2020-02-14
    相关资源
    最近更新 更多