根据关键字c#将文本文件解析为类的实例

时间:2017-07-05 21:17:09

标签: c# file parsing text

我有一个包含点列表的文本文件:

  

POINT:    5型,    对象ID 2,    设备类型CAT,    TAG' ADDRESS-1',    描述' kitty',    单位' Lb',

     

POINT:    5型,    对象ID 2,    设备类型CAT,    TAG' ADDRESS-2',    描述'橙色小猫',    单位' Lb',

     

POINT:    2型,    对象ID 3,    设备类型狗,    TAG' ADDRESS-5',    描述'棕色狗',    单位' Lb',

由此,我想创建我班级的实例(在本例中为2),Cat'包含此文本文件中的标记和描述(然后将它们放在Cats列表中)。我只想从类型5的点(那些是猫)中获取描述和标记。

我不确定获得我想要的字符串的最佳方法是什么。我需要在整个文件中搜索类型5的所有点,然后对于每个点,获取描述和标记并将其添加到新的Cat。

 public static void Main()
    {
        string line;
        List<Cat> catList = new List<Cat>();
        StreamReader file = new StreamReader(@"C:\Config\pets.txt");
        while((line = file.ReadLine()) != null)
        {
            string[] words = line.Split(',');
            catList.Add(new Cat cat1)
        }}

我最终这样做了:

 public static List<List<string>> Parse()
    {
        string filePath = @"C:\Config\pets.txt";
        string readText = File.ReadAllText(filePath);
        string[] stringSeparators = new string[] { "POINT:" }; //POINT is the keyword the text will be split on
        string[] result;


        result = readText.Split(stringSeparators, StringSplitOptions.None);
        List<List<string>> catData = new List<List<string>>();
        //split the text into an list of pieces
        List<string> tags = new List<string>(); //tags go here
        List<string> descriptions = new List<string>(); //descriptions go here
        foreach (string s in result)
        {
            if (s.Contains("TYPE 5")) //TYPE 5 = CAT
            {

                string[] parts = s.Split(','); //split the cat by commas
                string chop = "'"; //once tags and descriptions have been found, only want to keep what is inside single quotes ie 'orange kitty'
                foreach (string part in parts)
                {
                    if (part.Contains("TAG"))
                    {
                        int startIndex = part.IndexOf(chop);
                        int endIndex = part.LastIndexOf(chop);
                        int length = endIndex - startIndex + 1;
                        string path = part.Substring(startIndex, length);
                        tag = tag.Replace(chop, string.Empty);
                        tags.Add(tag);
                        //need to create instance of Cat with this tag
                    }
                    if (part.Contains("DESCRIPTION"))
                    {
                        int startIndex = part.IndexOf(chop);
                        int endIndex = part.LastIndexOf(chop);
                        int length = endIndex - startIndex + 1;
                        string description = part.Substring(startIndex, length);
                        description = description.Replace(chop, string.Empty);
                        descriptions.Add(description);
                        //need to add description to Cat instance that matches associated tag
                    }

                }
            }

        }

        catData.Add(tags);
        catData.Add(descriptions);
        return catData;

1 个答案:

答案 0 :(得分:0)

我要做的是创建一个表示您要捕获的字段的类。对于此示例,我正在捕获所有字段,但您可以根据需要自定义它。我称这个类为“动物”,因为看起来“点”代表动物。

然后我会在类中添加一个静态Parse方法,该方法将根据某个输入字符串返回Animal的实例。此方法将解析输入字符串,并尝试根据字符串中的值设置Animal对象的相关属性。

我还在课程上添加了ToString()覆盖,因此我们可以通过某种方式显示输出:

class Animal
{
    public int Type { get; set; }
    public int ObjectId { get; set; }
    public string DeviceType { get; set; }
    public string Tag { get; set; }
    public string Description { get; set; }
    public string Units { get; set; }

    /// <summary>
    /// Parses an input string and returns an Animal based
    /// on any property values found in the string
    /// </summary>
    /// <param name="input">The string to parse for property values</param>
    /// <returns>An animal instance with specified properties</returns>
    public static Animal Parse(string input)
    {
        var result = new Animal();
        if (string.IsNullOrWhiteSpace(input)) return result;

        // Parse input string and set fields accordingly
        var keyValueParts = input
            .Split(new [] {','}, StringSplitOptions.RemoveEmptyEntries)
            .Select(kvp => kvp.Trim());

        foreach (var keyValuePart in keyValueParts)
        {
            if (keyValuePart.StartsWith("Type", 
                StringComparison.OrdinalIgnoreCase))
            {
                int type;
                var value = keyValuePart.Substring("Type".Length).Trim();
                if (int.TryParse(value, out type))
                {
                    result.Type = type;
                }
            }
            else if (keyValuePart.StartsWith("Object Id", 
                StringComparison.OrdinalIgnoreCase))
            {
                int objectId;
                var value = keyValuePart.Substring("Object Id".Length).Trim();
                if (int.TryParse(value, out objectId))
                {
                    result.ObjectId = objectId;
                }
            }
            else if (keyValuePart.StartsWith("Device Type", 
                StringComparison.OrdinalIgnoreCase))
            {
                var value = keyValuePart.Substring("Device Type".Length).Trim();
                result.DeviceType = value;
            }
            else if (keyValuePart.StartsWith("Tag", 
                StringComparison.OrdinalIgnoreCase))
            {
                var value = keyValuePart.Substring("Tag".Length).Trim();
                result.Tag = value;
            }
            else if (keyValuePart.StartsWith("Description", 
                StringComparison.OrdinalIgnoreCase))
            {
                var value = keyValuePart.Substring("Description".Length).Trim();
                result.Description = value;
            }
            else if (keyValuePart.StartsWith("Units", 
                StringComparison.OrdinalIgnoreCase))
            {
                var value = keyValuePart.Substring("Units".Length).Trim();
                result.Units = value;
            }
        }

        return result;            
    }

    public override string ToString()
    {
        // Return a string that describes this animal
        var animalProperties = new StringBuilder();
        animalProperties.Append($"Type = {Type}, Object Id = {ObjectId}, ");
        animalProperties.Append($"Device Type = {DeviceType}, Tag = {Tag}, ");
        animalProperties.Append($"Description = {Description}, Units = {Units}");
        return animalProperties.ToString();
    }
}

既然我们有一个可以从字符串创建自己的对象,我们只需要读入文件内容,将其拆分为“Point:”关键字,然后将每个字符串传递给Animal类得到我们的实例。

我添加了一些System.Linq条款来过滤那些Type = 5(你说它们都是猫)的动物,因为你说这是你唯一感兴趣的动物。当然你可以删除这是为了得到所有的动物,或者用“狗”替换它以获得狗等等。:

private static void Main()
{
    var filePath = @"f:\public\temp\temp.txt";

    // Read all file contents and split it on the word "Point:"
    var fileContents = Regex
        .Split(File.ReadAllText(filePath), "Point:", RegexOptions.IgnoreCase)
        .Where(point => !string.IsNullOrWhiteSpace(point))
        .Select(point => point.Trim());

    // Get all animals that are cats from the results
    var catList = fileContents
        .Select(Animal.Parse)
        .Where(animal => animal.Type == 5)
        .ToList();

    // Output results
    catList.ForEach(Console.WriteLine);

    // Wait for input before closing
    Console.WriteLine("\nDone!\nPress any key to exit...");
    Console.ReadKey();
}

<强>输出

enter image description here