【问题标题】:Parsing Line Breaks from Plain Text从纯文本中解析换行符
【发布时间】:2020-07-07 03:42:57
【问题描述】:

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

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 的值。另一个占位符:值是不相关且随机的。

【问题讨论】:

  • 电子邮件是来自 Windows 还是 Linux? Linux 有不同的回报,这可能解释了这个问题。
  • @jdweng Windows.
  • 好吧,Info:More info: 是常量标签(或显示常量/可理解/可预测模式的元素)吗?你确定你没有任何 remains 的原始换行符(你是否解析了字节值)?你不能要求修改这个程序的功能吗?
  • 它们是我可以在电子邮件中查找的常量标签。我们使用的程序不是我们的应用程序,因此无法更改提取方式。
  • 那么,如果你有可预测的插入点,你能IndexOf()这些占位符吗?或者使用正则表达式,如果您在每个 placeholder 中有特定元素,则更有用?

标签: c# parsing


【解决方案1】:

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

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

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

EmailParserGetPartValue(string) 通过名称返回标识符的内容(名称可以包含或不包含冒号字符,例如 "Order""Order:")。
Matches 属性返回所有匹配标识符及其内容的Dictionary<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));
    }
}

【讨论】:

  • 我觉得我应该将此标记为答案,因为这肯定会对某人有所帮助,但我说错了。当你问我是否知道所有占位符时,我以为你指的是我关心的所有占位符。我不知道所有占位符,因为它是来自一个人的电子邮件。意思是,他们可以在技术上放置我不关心的某些占位符。
  • 我发布了一个带有一些术语替换的示例。在示例中,When: 7/10 对代表一个占位符:我不关心且一无所知的值。这带来的困难是您不知道占位符的值何时结束,因为您不能指望使用正则表达式中的“下一个”匹配作为子字符串。
  • 发布了另外 2 个示例。让我知道这是否有帮助。
  • 所有这些样本都有相同的标识符Order:The Total:When:Type:。这封电子邮件真的可以包含其他随机标识符吗?在这种情况下,这些是否总是包含颜色?其他地方,相关值,电子邮件正文或其他地方是否有冒号?这是您实际收到的所有文本吗?我只能根据你给我的信息采取行动……
  • 好的,我会看看是否可以一致地生成这些样本的部分。我会告诉你的。
猜你喜欢
  • 1970-01-01
  • 2023-04-05
  • 1970-01-01
  • 2013-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-08
  • 1970-01-01
相关资源
最近更新 更多