【问题标题】:C#: Help polishing string parsingC#:帮助打磨字符串解析
【发布时间】:2013-04-11 20:28:49
【问题描述】:

我在这个社区中真正看重的一件事是学习用两条线做事的方法,而这通常需要我 20 分钟。本着这种精神,我已尽我所能将一些字符串解析从十几行减少到三行。但我觉得有人想向我展示这实际上是多么的一团糟。只是为了我自己的熏陶,有没有更清洁的方法来做以下事情?可以一行完成吗?

string getThis = "<add key=\"messageFilter\" value=\"";
string subStr = strFile.Substring(strFile.IndexOf(getThis) + getThis.Length);
string[] igPhrases = subStr.Substring(0, subStr.IndexOf(";\"")).Split(';');

更新

感谢您的快速回复!真正有用的例子和好的建议,最少的蛇。 :) 更少的行与简洁和优雅是不一样的,减少行实际上可能会使代码变得更糟。

让我重新表述一下这个问题。

我有一个包含以下行的 XML 文档:&lt;add key="messageFilter" value="Out of Office AutoReply;Automatic reply;"/&gt;。该文档告诉我们的自动票务系统不要从主题行中包含这些短语的电子邮件中创建票证。否则,我们将陷入无限循环。

我正在开发一个小程序,该程序将列出已包含的短语,然后允许用户添加新短语。如果我们注意到一条新的自动回复消息开始在系统中循环,我们需要能够将该消息的语言添加到过滤器中。

我不经常使用 XML。我喜欢 Sperske 的解决方案,但我不知道如何使其动态化。换句话说,我不能将值放入我的代码中。我需要找到键“messageFilter”,然后获取与该键关联的所有值。

我所做的工作,但它似乎有点麻烦。有没有更直接的方法来获取关键值?并添加一个新的?

【问题讨论】:

  • 行数少并不意味着代码更干净
  • 在我不那么谦虚的意见中,我认为您不应该渴望编写尽可能少的代码行。我认为你应该渴望编写干净、清晰、易于理解、设计良好的代码。
  • 这只是更大的一部分吗?喜欢解析XML 文件?是这样 - 请告诉我们,有更好的方法来解析这些。
  • 嗯,看起来像 XML……你为什么不使用 XML API 来解析它?
  • 编写代码的三个标准...短、可读和高效。选择两个。一个经典的三角形:-)

标签: c# xml parsing


【解决方案1】:

一个略有不同的单行(为了便于阅读而拆分):

System.Xml.Linq.XDocument
  .Parse("<add key='messageFilter' value='AttrValue'/>")
  .Root
  .Attribute("value")
  .Value

输出:

AttrValue

要解决更新后的问题,您可以将所有 &lt;add&gt; 节点转换为字典(借用 Pako 的出色答案,并使用稍长的字符串):

var keys = System.Xml.Linq.XDocument
  .Parse("<keys><add key='messageFilter' value='AttrValue'/><add key='userFilter' value='AttrValueUser'/></keys>")
  .Descendants("add")
  .ToDictionary(r => r.Attribute("key").Value, r => r.Attribute("value").Value);

这使您可以像这样访问您的密钥:

keys["messageFilter"] == "AttrValue"
keys["userFilter"] == "AttrValueUser"

【讨论】:

  • 现在至于高效......好吧,我们只是说您可能需要放弃“单行”规则
  • +1 只是建议将其编辑为“两行”(包装)-这样看起来更容易:)
  • 更优雅!谢谢@JasonSperske!我已经更新了我的问题。我实际上需要更动态的东西,因为键值是可变的。
  • @tmoore82,我尝试在 Pako 的回答的基础上添加动态能力,希望对您有所帮助:)
【解决方案2】:

已经回答了,但是对于未来的读者来说——如果你想解析更大的 XML,带有根和许多 add 节点,你可能需要使用稍微不同的东西。

string xmlPart = "<add key=\"messageFilter\" value=\"\" />";
string xml = "<root>" + xmlPart + "</root>";
var x = XDocument.Parse(xmlPart, LoadOptions.None);

var attributes1 = x.Descendants("add").Select(n => n.Attributes());
var attributes2 = x.Descendants("add").SelectMany(n => n.Attributes());

这将为您提供IEnumerable&lt;IEnumerable&lt;XAttribute&gt;&gt;(请参阅attributes1)或IEnumerable&lt;XAttribue&gt;(请参阅attributes2)。第二个选项将简单地展平结果 - 所有属性都将保存在一个集合中,无论它们来自哪个节点。
当然,没有什么能阻止您按名称或其他标准过滤 XAttributes - 这完全取决于您!

【讨论】:

  • +1 我试图在我的答案中调整这个答案(希望我已经添加了更多),但仍然认为你应该以第一个深入的答案做出回应。
【解决方案3】:

一条丑陋的线:

string[] igPhrases = strFile.Substring(strFile.IndexOf(getThis) + ("<add key=\"messageFilter\" value=\"").Length).Substring(0, strFile.Substring(strFile.IndexOf("<add key=\"messageFilter\" value=\"") + ("<add key=\"messageFilter\" value=\"").Length).IndexOf(";\"")).Split(';');

【讨论】:

  • +1 用于执行 tmoore82 的要求,-1 用于添加似乎被误导的方法:P
  • 我不想调试这个。
  • 谢谢!这正是我想要的!根据给我的建议,我可能会走另一条路,但看看我的目标真的很有帮助,Artem。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-03
  • 2021-01-24
  • 1970-01-01
相关资源
最近更新 更多