C#将字符串行拆分为多个字符串

3
我正在尝试将一些cmd输出分成多个字符串,以便稍后用于设置标签。
我使用的代码是:
ProcessStartInfo diskdrive = new ProcessStartInfo("wmic", " diskdrive get index, model, interfacetype, size");
diskdrive.UseShellExecute = false;
diskdrive.RedirectStandardOutput = true;
diskdrive.CreateNoWindow = true;
var proc = Process.Start(diskdrive);

string s = proc.StandardOutput.ReadToEnd();

它会输出类似这样的结果:
Index  InterfaceType  Model                   Size           
2      IDE            WesternDigital    1000202273280  
1      IDE            Seagate             500105249280   
0      IDE            SAMSUNG SSD 830 Series  128034708480

能否将这些内容放在列表或数组中,以便我可以获取例如磁盘2的大小或磁盘0的接口类型。我可以用C#做一些基本的事情,但这超出了我的能力范围 :I


你尝试过使用 String.Split 吗?或者是使用 Regex - Kryptos
如果某些单元格中有空格(例如“SAMSUNG SSD 830 Series”),则使用String.Split会出现问题。 - adv12
字符串分割在这里行不通,因为我不知道如何处理其中的空格。 - Zenkaipu
4
不需要使用外部应用程序获取WMI信息,您可以直接在C#中查询WMI,然后可以直接访问每个数据字段,无需拆分任何字符串。 C#中的WMI查询是收集有关系统信息的SQL查询。例如:var allPDisks = Session.QueryInstances(@"root\microsoft\windows\storage", "WQL", "SELECT * FROM MSFT_PhysicalDisk") MSFT_PhysicalDisk类提供了您想要获取的所有字段。请参见此链接 - Chris Dunaway
你需要从事实开始:始终会有4列,第一列和最后一列始终是数字;尝试从这些信息反推出剩余的列并进行解析,然后你就可以构建你的列表了。 - Paul
问题中给出的输出是否正确?据我所知,wmic以固定宽度列输出数据。这表明Size列的对齐方式与wmic输出的不同。 - Martin Brown
2个回答

1

这是一个可用的示例。"result"将包含您所需的相关部分列表。这是第一遍,我相信可以进行一些重构:

using System;
using System.Collections.Generic;
using System.Linq;

namespace columnmatch
{
    internal class Program
    {

        private const string Ex1 = "2      IDE            WesternDigital    1000202273280";
        private const string Ex2 = "1      IDE            Seagate             500105249280 ";
        private const string Ex3 = "0      IDE            SAMSUNG SSD 830 Series  128034708480";

        private static void Main(string[] args)
        {
            var result = new List<MyModel>();
            result.Add(ParseItem(Ex1));
            result.Add(ParseItem(Ex2));
            result.Add(ParseItem(Ex3));
        }

        private static MyModel ParseItem(string example)
        {
            var columnSplit = example.Split((char[]) null, StringSplitOptions.RemoveEmptyEntries);

            int index = -1;
            string interfaceType = string.Empty;
            long size = -1;
            string model = string.Empty;

            if (columnSplit.Count() == 4)
            {
                //direct match (no spaces in input)
                index = Convert.ToInt32(columnSplit[0]);
                interfaceType = columnSplit[1];
                model = columnSplit[2];
                size = Convert.ToInt64(columnSplit[3]);
            }
            else
            {
                string modelDescription = string.Empty;

                for (int i = 0; i < columnSplit.Count(); i++)
                {
                    if (i == 0)
                    {
                        index = Convert.ToInt32(columnSplit[i]);
                    }
                    else if (i == 1)
                    {
                        interfaceType = columnSplit[i];
                    }
                    else if (i == columnSplit.Count() - 1) //last
                    {
                        size = Convert.ToInt64(columnSplit[i]);
                    }
                    else
                    {
                        //build the model
                        modelDescription += columnSplit[i] + ' ';
                    }
                }

                model = modelDescription.TrimEnd();
            }

            var myItem = BuildResultItem(index, interfaceType, model, size);
            return myItem;
        }

        private static MyModel BuildResultItem(int index, string interfaceType, string model, long size)
        {
            var myItem = new MyModel
            {
                Index = index,
                InterfaceType = interfaceType,
                Model = model,
                Size = size
            };

            return myItem;
        }

        private class MyModel
        {
            public int Index { get; set; }
            public string InterfaceType { get; set; }
            public string Model { get; set; }
            public long Size { get; set; }
        }
    }
}

这个答案遵循了我评论中的事实:始终会有4列,第一列和最后一列总是数字,并且依此递增。

0

看起来你运行的命令确保每列之间有一个双空格。然后只需要对双字符串进行字符串拆分。

所以,给定你的字符串s,这对我来说是有效的:

var map =
    s
        .Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries)
        .Skip(1)
        .Select(x => x.Split(new [] { "  " }, StringSplitOptions.RemoveEmptyEntries))
        .Select(x => x.Select(y => y.Trim()).ToArray())
        .ToDictionary(
            x => int.Parse(x[0]),
            x => new
            {
                InterfaceType = x[1],
                Model = x[2],
                Size = ulong.Parse(x[3]),
            });

然后我可以做:

string it = map[0].InterfaceType;
ulong size = map[2].Size;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接