首页 > 解决方案 > 从纯文本中解析换行符

问题描述

我有一个解析电子邮件的过程。我们用来检索和存储正文内容的软件似乎不包括换行符,所以我最终得到了这样的东西 -

Good afternoon, [line-break] this is my email. [line-break] Info: data [line-break] More info: data

我的 [line-break] 括号是换行符应该在的位置。然而,当我们提取正文时,我们得到的只是文本。在没有换行符的情况下解析文本变得很困难。

本质上,我需要做的是解析每个[Info]: [Data]. 我可以找到[Info]标签的开始位置,但是没有换行符,我很难知道与该信息关联的数据应该在哪里结束。电子邮件来自 Windows。

有什么方法可以获取纯文本并将其编码为某种包括换行符的方式?

示例电子邮件内容

Good Morning, Order: 1234 The Total: $445 When: 7/10 Type: Dry

Good Morning, Order: 1235 The Total: $1743 Type: Frozen When: 7/22

Order: 1236 The Total: $950.14 Type: DRY When: 7/10

The Total: $514 Order: 1237 Type: Dry CSR: Tim W

Sorry, below is your order: Order: 1236 The Total: $500 When: 7/10 Type: Dry Creator: Josh A. Thank you

现在,我需要遍历电子邮件并解析出 Order、Total 和 Type 的值。另一个占位符:值是不相关且随机的。

标签: c#parsing

解决方案


尝试这样的事情。
您需要添加所有可能的部分标识符:它可以随着时间的推移而更新,以添加更多已知的标识符,以减少解析字符串时出错的机会。

到目前为止,如果在解析字符串时由已知标识符标记的值包含未知标识符,则该部分将被删除。
如果遇到未知标识符,则将其忽略。

Regex.Matches将提取所有匹配的部分,返回它们的值、索引位置和长度,因此使用它[Input].SubString(Index, NextPosition - Index)返回与请求的部分对应的值很简单。

该类通过其名称返回标识符的内容(名称可以包含或不包含冒号字符,例如EmailParser或)。属性返回所有匹配 的标识符及其内容。内容被清理——尽可能——调用方法。GetPartValue(string)"Order""Order:"
MatchesDictionary<string, string>CleanUpValue()

调整此方法以处理一些特定/未来的要求。

► 如果您不传递 Pattern 字符串,则使用默认字符串。
► 如果您更改模式、设置CurrentPatter属性(可能使用存储在应用程序设置中或在 GUI 或其他任何内容中编辑的模式),匹配值的字典将被重建。

初始化:

string input = "Good Morning,  Order: 1234 The Total: $445 Unknown: some value Type: Dry When: 7/10";
var parser = new EmailParser(input);
string value = parser.GetPartValue("The Total");
var values = parser.Matches;

public class EmailParser
{
    static string m_Pattern = "Order:|The Total:|Type:|Creator:|When:|CSR:";

    public EmailParser(string email) : this(email, null) { }
    public EmailParser(string email, string pattern)
    {
        if (!string.IsNullOrEmpty(pattern)) {
            m_Pattern = pattern;
        }
        Email = email;
        this.Matches = GetMatches();
    }

    public string Email { get; }

    public Dictionary<string, string> Matches { get; private set; }

    public string CurrentPatter {
        get => m_Pattern;
        set {
            if (value != m_Pattern) {
                m_Pattern = value;
                this.Matches = GetMatches();
            }
        }
    }

    public string GetPartValue(string part)
    {
        if (part[part.Length - 1] != ':') part += ':';
        if (!Matches.Any(m => m.Key.Equals(part))) {
            throw new ArgumentException("Part non included");
        }
        return Matches.FirstOrDefault(m => m.Key.Equals(part)).Value;
    }

    private Dictionary<string, string> GetMatches()
    {
        var dict = new Dictionary<string, string>();
        var matches = Regex.Matches(Email, m_Pattern, RegexOptions.Singleline);

        foreach (Match m in matches) {
            int startPosition = m.Index + m.Length;
            var next = m.NextMatch();
            string parsed = next.Success
                ? Email.Substring(startPosition, next.Index - startPosition).Trim()
                : Email.Substring(startPosition).Trim();

            dict.Add(m.Value, CleanUpValue(parsed));
        }
        return dict;
    }

    private string CleanUpValue(string value)
    {
        int pos = value.IndexOf(':');
        if (pos < 0) return value;
        return value.Substring(0, value.LastIndexOf((char)32, pos));
    }
}

推荐阅读