C#正在分析要输出的关键字行

本文关键字:输出 关键字 | 更新日期: 2023-09-27 18:28:23

我们正试图对在正常维护周期外应用的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文本框中,单击一个按钮,并在另一个富格文本框中获得所需的输出。有一种"关键字:数据"的模式可能很有用。

我已经创建了表单和表单上的元素。我试图找到一个搜索关键字的方法,但这不会产生我们想要的结果。可以说,我们想要关键字或行,正如你所看到的,描述可以是多行。

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

C#正在分析要输出的关键字行

您可以尝试以下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");

模式说明:

(?<=):是正面向后看的表示法。

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

.*:匹配look-behind之后的任何内容,它本质上是Keyword: Data对中的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条目。我不确定您的需求是什么,但这只是对列表进行迭代的一个示例。根据您的需要进行更改。

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

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

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)你可以做很多简单的重构。