0

我将收到的消息添加到通过串行端口从 GSM 调制解调器读取的文本文件中。稍后我使用正则表达式解析这些消息并将它们显示在列表视图中。接收单行消息并显示它们都很好,但是当我收到多行消息时,我无法阅读它们。我想我应该改变我用来解析的正则表达式。建议请..

    public ShortMessageCollection ParseMessages(string input)
    {
        ShortMessageCollection messages = new ShortMessageCollection();
        Regex r = new Regex(@"\+CMGL: (\d+),""(.+)"",""(.+)"",(.*),""(.+)""\r\n(.+)\r\n");
        Match m = r.Match(input);
        while (m.Success)
            {
                ShortMessage msg = new ShortMessage();
                msg.Index = m.Groups[1].Value;
                msg.Status = m.Groups[2].Value;
                msg.Sender = m.Groups[3].Value;
                msg.Alphabet = m.Groups[4].Value;
                msg.Sent = m.Groups[5].Value;
                msg.Message = m.Groups[6].Value;
                messages.Add(msg);
                m = m.NextMatch();
            }

        return messages;
     }

input是一个字符串变量,它包含从文件中读取的数据。单行消息input是这样的:

+CMGL: 1,\"REC UNREAD\",\"IA-612345\",\"\",\"2012/08/14 12:56:46+22\"\r\nRecharge with RC45 & get 100 local minutes valid for 15days.For details call 53640 (Toll Free)\r\n\r\n

多行消息是这样的:

+CMGL: 1,\"REC READ\",\"+919909965834\",\"\",\"2012/08/17 09:55:29+22\"\r\nHai helo\nthis is a\ntest mesg\r\n\r\nOK\r\n

如何正确完整地阅读多行消息中的消息部分?

4

3 回答 3

0

如果要将 .NetRegex与多行文本进行匹配,则需要提供RegexOptions.Multiline构造函数参数:

public ShortMessageCollection ParseMessages(string input)
{
    ShortMessageCollection messages = new ShortMessageCollection();
    Regex r = new Regex(
        @"\+CMGL: (\d+),""(.+)"",""(.+)"",(.*),""(.+)""\r\n(.+)\r\n",
        RegexOptions.Multiline);
    Match m = r.Match(input);
    while (m.Success)
    {
        ShortMessage msg = new ShortMessage();
        msg.Index = m.Groups[1].Value;
        msg.Status = m.Groups[2].Value;
        msg.Sender = m.Groups[3].Value;
        msg.Alphabet = m.Groups[4].Value;
        msg.Sent = m.Groups[5].Value;
        msg.Message = m.Groups[6].Value;
        messages.Add(msg);
        m = m.NextMatch();
    }

    return messages;
}
于 2012-08-17T05:24:21.980 回答
0

尝试使用这个正则表达式。它包括 \r 和 \n 作为最后一组中的可匹配字符。这样做的一个问题是它过滤掉了 \n 和 \r 字符。如果您还想捕获这些,您可以?:从表达式中删除 以使该捕获也有效。

"\+CMGL: (\d+),""(.+)"",""(.+)"",(.*),""(.+)""\r\n([^\r]+)\r\n"
于 2012-08-17T05:53:55.210 回答
0

您可能会考虑不尝试使用正则表达式来解决整个问题。看起来您的数据至少有一部分是结构化的,因此您可以为此使用正则表达式。对于消息的实际正文,您可以只阅读行直到没有更多行,然后再次匹配标题。

尝试类似:

var r = new Regex(@"\+CMGL: (\d+),""(.+)"",""(.+)"",(.*),""(.+)""",
                  RegexOptions.Compiled);
var messages = new ShortMessageCollection();
using (var sw = new StringReader(input))
{
    string currentLine = sw.ReadLine();
    while (currentLine != null)
    {
        var m = r.Match(currentLine);
        if (m.Success)
        {
            // read the first line of the message
            string message = string.Empty;
            currentLine = sw.ReadLine();

            // Append any extra lines to our message, unless it's a new record
            while (currentLine != null && !r.IsMatch(currentLine))
            {
                message += Environment.NewLine;
                message += currentLine;

                currentLine = sw.ReadLine();
            }

            messages.Add(new ShortMessage
                             {
                                 Index = m.Groups[1].Value,
                                 Status = m.Groups[2].Value,
                                 Sender = m.Groups[3].Value,
                                 Alphabet = m.Groups[4].Value,
                                 Sent = m.Groups[5].Value,
                                 Message = message,
                             });
        }
        else
        {
            // TODO: Log that a line didn't match
            // it could be empty or otherwise invalid
            currentLine = sw.ReadLine();
        }
    }
}

这只是您可以做什么的粗略概述。如果您想处理大量数据,我强烈建议您在单个正则表达式上使用这样的方法(不一定是此代码)。这使用了 TextReader,因此如果您从几 GB 大的文件中逐行读取,它将立即起作用。

于 2012-08-17T07:29:54.403 回答