C#解析输出的关键字行

时间:2014-10-29 18:16:58

标签: c# parsing richtextbox

我们正在尝试更新我们在正常维护周期期间应用的Microsoft KBase更新。 我们想解析下面针对特定行的信息。样本如下:

Operation           : 1
ResultCode          : 2
HResult             : 0
Date                : 10/7/2014 10:27:50 AM
UpdateIdentity      : System.__ComObject
Title               : Update for Microsoft Silverlight (KB2977218)
Description         : This update to Silverlight improves security, reliability, accessibility support, startup performance, enhances line-of-business support and includes several fixes to better support rich internet applications. This update is backward compatible with web applications built using previous versions of Silverlight.
UnmappedResultCode  : 0
ClientApplicationID : AutomaticUpdates
ServerSelection     : 1
ServiceID           : 
UninstallationSteps : System.__ComObject
UninstallationNotes : 
SupportUrl          : http://go.microsoft.com/fwlink/?LinkID=105787
Categories          : System.__ComObject

我们的期望输出是:

Title               : Update for Microsoft Silverlight (KB2977218)
Date                : 10/7/2014 10:27:50 AM
Description         : This update to Silverlight improves security, reliability, accessibility support, startup performance, enhances line-of-business support and includes several fixes to better support rich internet applications. This update is backward compatible with web applications built using previous versions of Silverlight.

我正在尝试编写一个简单的C#应用​​程序,我们将原始数据粘贴到Rich文本框中,单击一个按钮并在另一个Rich文本框中显示所需的输出。有一种模式"关键字:数据"这可能有用。

我创建了表单和表单上的元素。我试图找到一个搜索关键字的方法,但这不会产生我们寻求的结果。我们想要关键字或行,因为您可以看到描述可能是多行。

我目前没有任何示例代码要发布,因为我不知道从哪里开始执行此任务。任何示例代码都有助于完成此任务。

2 个答案:

答案 0 :(得分:1)

您可以尝试以下Regex模式:

(?<=\b[KEYWORD]\b\s*:\s*).*

只需将[KEYWORD]替换为您正在寻找的实际关键字。例如,(?<=\bTitle\b\s*:\s*).*将返回Update for Microsoft Silverlight (KB2977218)。以下是您在代码中使用它的方式:

private string GetDataFromKeyword(string source, string keyword)
{
    return Regex.Match(source, string.Format(@"(?<=\b{0}\b\s*:\s*).*", keyword)).Value.Trim();
}

并称之为:

string data = GetDataFromKeyword(textbox.Text, "Title");

模式说明:

(?<=):是positive look-behind的符号。

\b[KEYWORD]\b\s*:\s*:匹配整个单词[KEYWORD],后跟任意数量的空格,后跟:后跟任意数量的空格。

.*:匹配后面的任何内容,基本上是Data对中的Keyword: Data

修改

如果您有给定关键字的多个实例,则可以使用Matches()方法而不是Match()

private IEnumerable<string> GetDataFromKeyword(string source, string keyword)
{
    return Regex.Matches(source, string.Format(@"(?<=\b{0}\b\s*:\s*).*", keyword))
            .Cast<Match>().Select(match => match.Value.Trim());
}

现在var data = GetDataFromKeyword(textbox.Text, "Title");会返回您可以枚举的匹配列表:

var titles = GetDataFromKeyword(textbox.Text, "Title").ToArray();
var dates = GetDataFromKeyword(textbox.Text, "Date").ToArray();
var descriptions = GetDataFromKeyword(textbox.Text, "Description").ToArray();

for (int i = 0; i < titles.Count(); i++)
{
    string block = string.Format("Title: {0}, Date: {1}, Description: {2}", titles[i], dates[i], descriptions[i]);
    MessageBox.Show(string.Format("Block {0}: {1}", i+1, block));
}

请注意,这假设您拥有相同数量的 titledatedescription条目。我不确定你的要求是什么,但这只是迭代列表的一个例子。根据您的需求进行更改。

答案 1 :(得分:1)

我通常不喜欢基于正则表达式的解决方案 - 几乎总有一种可读方式来实现您的目标。

这样的事情应该让你开始。很多重构的机会:

var keywords = new List<string>() { "Keyword1", "Keyword2", "Keyword3" };

var lines = File.ReadLines(@"c:\path\to\file.txt");

foreach (var line in lines)
{
    foreach (var keyword in keywords)
    {
        if (line.StartsWith(keyword))
        {
            // found a match, do something.
            // Split on ":"? etc.
        }
    }
}

正如我所说,非常快速和肮脏,但1)它的工作2)它是可读的3)你可以做很多简单的重构。