c# - 从纯文本中解析换行符
问题描述
我有一个解析电子邮件的过程。我们用来检索和存储正文内容的软件似乎不包括换行符,所以我最终得到了这样的东西 -
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 的值。另一个占位符:值是不相关且随机的。
解决方案
尝试这样的事情。
您需要添加所有可能的部分标识符:它可以随着时间的推移而更新,以添加更多已知的标识符,以减少解析字符串时出错的机会。
到目前为止,如果在解析字符串时由已知标识符标记的值包含未知标识符,则该部分将被删除。
如果遇到未知标识符,则将其忽略。
Regex.Matches
将提取所有匹配的部分,返回它们的值、索引位置和长度,因此使用它[Input].SubString(Index, NextPosition - Index)
返回与请求的部分对应的值很简单。
该类通过其名称返回标识符的内容(名称可以包含或不包含冒号字符,例如EmailParser
或)。属性返回所有匹配
的标识符及其内容。内容被清理——尽可能——调用方法。GetPartValue(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));
}
}