【问题标题】:Unable to read a line of text that is broken, from a text file- C#无法从文本文件中读取一行损坏的文本-C#
【发布时间】:2012-08-17 04:59:42
【问题描述】:

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

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

【问题讨论】:

  • 邮件是否总是以\r\n开头?
  • 是的。它总是从一个新行开始

标签: c# regex winforms sms multiline


【解决方案1】:

如果您想将 .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;
}

【讨论】:

  • 很抱歉,但这一点有什么不同。多行消息与正则表达式不匹配
  • 如果您发布包含匹配项的目标字符串示例,我会尝试看看我能做些什么来调整您的 Regex 以使其匹配。
  • 我在问题中提到的单行消息与我编写的模式匹配。你可以参考一下
【解决方案2】:

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

尝试类似:

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 大的文件中逐行读取,它会立即工作。

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

    • 努力工作。这与我的文本文件中的整个数据匹配,并将字符串中的所有内容显示为一条消息:(
    • 我允许?: 和没有?: 但两者都给出了相同的结果
    • 如果所有这些消息都堆叠在一起,没有其他分隔符,那么将无法区分最后一次捕获的结尾(.|\r|\n)+ 和第一次捕获的开头。您将需要在消息之间使用其他类型的分隔符。
    • 这是多行消息Hai helo\nthis is a \ntest mesg 中的消息部分。那么现在在最后一组中,我不可能和\n一起阅读这些文字吗?如果这是可能的,那么休息很容易。
    • 所以请告诉我如何阅读最后一组中的words\n
    猜你喜欢
    • 1970-01-01
    • 2020-07-24
    • 2018-04-27
    • 2013-04-01
    • 2021-05-08
    • 2017-02-22
    • 2011-10-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多