无法从文本文件中读取一行文本 - C#

时间:2012-08-17 04:59:43

标签: c# regex winforms sms multiline

我将收到的消息添加到通过串口从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

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

3 个答案:

答案 0 :(得分:0)

如果要将.Net Regex与多行文本匹配,则需要提供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;
}

答案 1 :(得分:0)

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

"\+CMGL: (\d+),""(.+)"",""(.+)"",(.*),""(.+)""\r\n([^\r]+)\r\n"

答案 2 :(得分: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大的文件中逐行读取它会立即起作用。