我们正在尝试更新我们在正常维护周期期间应用的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文本框中显示所需的输出。有一种模式"关键字:数据"这可能有用。
我创建了表单和表单上的元素。我试图找到一个搜索关键字的方法,但这不会产生我们寻求的结果。我们想要关键字或行,因为您可以看到描述可能是多行。
我目前没有任何示例代码要发布,因为我不知道从哪里开始执行此任务。任何示例代码都有助于完成此任务。
答案 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));
}
请注意,这假设您拥有相同数量的 title
,date
和description
条目。我不确定你的要求是什么,但这只是迭代列表的一个例子。根据您的需求进行更改。
答案 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)你可以做很多简单的重构。