以面向对象的方式验证文本文件的分隔行

本文关键字:隔行 文件 文本 面向对象的 方式 验证 | 更新日期: 2023-09-27 18:12:48

文本文件中有一个用管道分隔的行。验证这一行的最好方法是什么?我有一个明确的格式,说明一行中的每个标记应该如何,例如;第五项应该是约会。

谁能帮我什么是最好的面向对象的方式来实现这一点?有什么设计模式可以做到这一点吗?

谢谢

以面向对象的方式验证文本文件的分隔行

您正在寻找用于验证的特定模式。可以通过多种方式进行验证,但最简单的方法是在对象的构造函数中进行验证。由于您正在寻找一种更加面向对象的方法,您可能会考虑创建一个对象来表示文件和一个对象来表示每条记录。除了联想,这里没有什么真正的模式。但是,您可以利用迭代器模式来允许在循环中迭代记录。您正在讨论读取一个文本文件,因此这不是一个足够复杂的过程,但如果是,您可以考虑使用工厂模式来创建文件对象。如果有很多东西需要验证,那么您可以创建一个单独的方法来验证类中的每一个。这是我正在谈论的一个例子…

 static void Main(string[] args)
    {
        DataFile myFile = new DataFile(@"C:'...");
        foreach (DataRecord item in myFile)
        {
            Console.WriteLine("ID: {0}, Name: {1}, StartDate: {2}", item.ID, item.Name, item.StartDate);
        }
        Console.ReadLine();
    }

    public class DataFile : IEnumerable<DataRecord>
    {
        HashSet<DataRecord> _items = new HashSet<DataRecord>();

        public DataFile(string filePath)
        {
            // read your file and obtain record data here... 
            //I'm not showing that
            //... then begin iterating through your string results
            //... though I'm only showing one record for this example
            DataRecord record = new DataRecord("1234|11-4-2015|John Doe");
            _items.Add(record);
        }

        public IEnumerator<DataRecord> GetEnumerator()
        {
            foreach (DataRecord item in _items)
            {
                yield return item;
            }
        }
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }
    public class DataRecord
    {
        private int _id;
        public int ID
        {
            get { return _id; }
            private set { _id = value; }
        }
        private DateTime _startDate;
        public DateTime StartDate
        {
            get { return _startDate; }
            private set { _startDate = value; }
        }
        private string _name;
        public string Name
        {
            get { return _name; }
            private set { _name = value; }
        }
        internal DataRecord(string delimitedRecord)
        {
            if (delimitedRecord == null)
                throw new ArgumentNullException("delimitedRecord");
            string[] items = delimitedRecord.Split('|');

            //You could put these in separate methods if there's a lot
            int id = 0;
            if (!int.TryParse(items[0], out id))
                throw new InvalidOperationException("Invalid type...");
            this.ID = id;
            DateTime startDate = DateTime.MinValue;
            if (!DateTime.TryParse(items[1], out startDate))
                throw new InvalidOperationException("Invalid type...");
            this.StartDate = startDate;
            //This one shouldn't need validation since it's already a string and 
            //will probably be taken as-is
            string name = items[2];
            if (string.IsNullOrEmpty(name))
                throw new InvalidOperationException("Invalid type...");
            this.Name = name;
        }

    }

实现这一点的"干净"的方法是使用正则表达式。下面是一个基本的例子:

var allLines = new List<string>();
for (int i = 0; i < 5; i++)
{
     allLines.Add("test" + i);
}
// if you add this line, it will fail because the last line doesn't match the reg ex
allLines.Add("test");
var myRegEx = @"'w*'d"; // <- find the regex that match your lines
Regex regex = new Regex(myRegEx);
var success = allLines.All(line => regex.Match(line).Success);

在这个例子中,我的正则表达式正在等待一个紧接一个数字的单词。您所要做的就是找到与您的行匹配的正则表达式。

您还可以通过使用更复杂的正则表达式来避免使用linq表达式。