用C#和字典解析<;字符串,字符串>;
我是编程新手,一直在努力解析文件。一、 起初,我们试图以某种方式解析它,但最终无法正常工作。我想解析字典用C#和字典解析<;字符串,字符串>;,c#,.net,text-parsing,C#,.net,Text Parsing,我是编程新手,一直在努力解析文件。一、 起初,我们试图以某种方式解析它,但最终无法正常工作。我想解析字典中的以下行 网卡:已安装7个NIC [01]: Broadcom Connection Name: Local Area Connection DHCP Enabled: No
[01]: Broadcom
Connection Name: Local Area Connection
DHCP Enabled: No
IP address(es)
[01]: abc.de.xyz.
[02]: Broadcom
Connection Name: eth1
Status: Media disconnected
[03]: Broadcom
Connection Name: eth0
Status: Media disconnected
[04]: Broadcom
Connection Name: eth3
Status: Media disconnected
[05]: Mellanox
Connection Name: Local Area Connection 5
Status: Hardware not present
[06]: Mellanox
Connection Name: Local Area Connection 6
Status: Media disconnected
[07]: Mellanox
Connection Name: Local Area Connection 7
DHCP Enabled: No
IP address(es)
[01]: mno.pqr.stu.vwx
我希望[01]Broadcom作为字典的键,连接名称:局域网连接DHCP已启用:无IP地址[01]:abc.de.xyz作为其他六个的值,依此类推。谢谢你的帮助。非常感谢。任何关于如何进行这项工作的帮助都将非常有用,因为我已经疯狂地阅读了关于拆分字符串的书籍,并试图找出如何让字典存储值。请原谅任何糟糕的C#语法-我已经习惯了VB.NET。别笑
我会先将文件的文本行读入字符串数组
foreach (string line in File.ReadLines("path-to-file")) {
}
对于每一行,您要么在“关键”行,要么在“价值”行。关键行如下所示:
[01]: Broadcom
var networkCards = new Dictionary<String, String>();
string currentKey = String.Empty;
foreach (string line in File.ReadLines("path-to-file")) {
if ( IsKeyLine( line ) ) {
currentKey = line.Trim();
networkCards.Add(currentKey, "");
} else {
networkCards[currentKey] += line.Trim() + " ";
}
}
要确定您是否在“关键”行上,您可以尝试类似于line.Trim().StartsWith(“[”
)的操作,但这无法可靠地工作,因为您还有其他类似[01]的行:abc.def.ghi.jkl
哪些是IP地址,而不是密钥。因此,您需要更聪明一点,甚至可以使用正则表达式来检测您是否正在查看IP地址或网卡。我不知道您正在查看的文件的确切规格,但您也可以使用前导空格/制表符来帮助您确定您是在“关键”行还是在“价值”行
您的代码将如下所示:
[01]: Broadcom
var networkCards = new Dictionary<String, String>();
string currentKey = String.Empty;
foreach (string line in File.ReadLines("path-to-file")) {
if ( IsKeyLine( line ) ) {
currentKey = line.Trim();
networkCards.Add(currentKey, "");
} else {
networkCards[currentKey] += line.Trim() + " ";
}
}
现在,我没有花时间测试任何代码-这是我的想法。但它至少应该让您朝着正确的方向前进。但最需要确定的是文件格式的标准。这将为您提供正确路径的线索。您甚至可能不需要正则表达式(这是最好的,因为正则表达式的运行成本通常很高)。考虑利用前导空格来确定行所扮演的“角色”(嘿,Python;-)。然后可以使用简单的状态机逐行解析文件
我怀疑,由于这是生成的输出,所以该方法可以可靠地使用。如果是这样,它将大大简化规则和解析
快乐编码
这里是一个小的概念证明,以确定该行的“角色”
using (var inp = ...) {
string line;
while ((line = inp.ReadLine()) != null) {
// normalize to our world of 8-space tabs
line = line.Replace("\t", " ");
var lineDepth = line.Length - line.TrimStart().Length;
if (lineDepth < 65) {
// is potential "heading line"
} else { // >= 65
// is "property line"
}
}
}
使用(var inp=…){
弦线;
而((line=inp.ReadLine())!=null){
//标准化为我们的8空间标签世界
行=行。替换(“\t”和“);
var lineDepth=line.Length-line.TrimStart().Length;
如果(线深<65){
//是潜在的“航向线”
}否则{/>=65
//是“建筑红线”
}
}
}
您还可以计算每行开头的制表符/空格,以指示该行所属的位置。如果您不想使用正则表达式,这里有一个解决方案。此代码已经过测试
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace NicParser
{
public class NicFileParser
{
private readonly string _file;
private readonly Dictionary<string, string> _nics;
public NicFileParser(string file)
{
_file = file;
_nics = new Dictionary<string, string>();
}
public void Parse()
{
var key = string.Empty;
var value = new StringBuilder();
try
{
using (var rdr = new StreamReader(_file))
{
var firstTime = true;
while (rdr.Peek() > 0)
{
var line = rdr.ReadLine().Trim();
if (IsKey(line))
{
// Once a key is hit, add the previous
// key and values (except the first time).
if (!firstTime)
{
_nics.Add(key, value.ToString());
}
else
{
firstTime = false;
}
// Assign the key, and clear the previous values.
key = line;
value.Length = 0;
}
else
{
// Add to the values for this nic card.
value.AppendLine(line);
}
}
// Final line of the file has been read.
// Add the last nic card.
_nics.Add(key, value.ToString());
}
}
catch (Exception ex)
{
// Handle your exceptions however you like...
}
}
private static bool IsKey(string line)
{
return (!String.IsNullOrEmpty(line)
&& line.StartsWith("[")
&& !line.Contains("."));
}
// Use this to access the NIC information.
public Dictionary<string, string> Cards
{
get { return _nics; }
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.IO;
使用系统文本;
名称空间语法分析器
{
公共类文件解析器
{
私有只读字符串\u文件;
专用只读词典;
公共文件分析器(字符串文件)
{
_文件=文件;
_nics=新字典();
}
公共空解析()
{
var key=string.Empty;
var值=新的StringBuilder();
尝试
{
使用(var rdr=newstreamreader(_文件))
{
var firstTime=true;
而(rdr.Peek()>0)
{
var line=rdr.ReadLine().Trim();
if(IsKey(行))
{
//按下一个键后,添加上一个
//键和值(第一次除外)。
如果(!第一次)
{
_添加(key,value.ToString());
}
其他的
{
第一次=错误;
}
//指定键,然后清除以前的值。
键=行;
值。长度=0;
}
其他的
{
//添加到此nic卡的值。
值。追加行(行);
}
}
//文件的最后一行已被读取。
//添加最后一个nic卡。
_添加(key,value.ToString());
}
}
捕获(例外情况除外)
{
//不管你怎么处理你的异常。。。
}
}
专用静态bool IsKey(字符串行)
{
返回(!String.IsNullOrEmpty(行)
&&行。以(“[”)开头
&&!line.Contains(“.”);
}
//使用此选项可访问NIC信息。
公共字典卡
{
获取{return\u nics;}
}
}
}
< /代码> 我知道,这个问题是关于c*,而不是关于<强> PopeStult,并且已经有一些很好的C语言答案,我仍然想贡献一个<强> PuthSu壳解决方案,作为一个需要考虑的问题。它可以比C代码更简单,但是这取决于观点:
$networkCards = systeminfo | ForEach-Object {$a=0} {
if ($_.startswith("Network Card(s)")) {$a=1} else {if ($a) {$_}}
}
$networkCards | ForEach-Object {$data=@{}} {
if ($_.trim().startswith("[")) {
$c = $_.trim(); $data[$c] = @()} else {$data[$c] += $_.trim()
}
}
#Now we have a hash table with the keys as requested in the question
#and the values are lists of separate strings, but those can be easily
#concatenated if needed. Let's display it:
$data
如果您安装了powershell(它现在是Windows 7的一部分),您只需打开它并在命令提示下粘贴上面的代码即可