4

我有一个文本文件,其中包含一些特定格式的赞美诗。示例如下。


1  Praise to the Lord

1 Praise to the Lord, the Almighty, the King of creation! O my soul, praise Him, for He is thy health and salvation! All ye who hear, now to His temple draw near; Join ye in glad adoration!

2 Praise to the Lord, Who o'er all things so wondrously reigneth, Shieldeth thee under His wings, yea, so gently sustaineth! Hast thou not seen how thy desires e'er have been Granted in what He ordaineth?

3 Praise to the Lord, who doth prosper thy work and defend thee; Surely His goodness and mercy here daily attend thee. Ponder anew what the Almighty can do, If with His love He befriend thee.

我想提取这些赞美诗,将它们放入对象中,然后将它们插入 SQLite 数据库。我正在尝试将它们相应地分开,但到目前为止我还没有取得任何进展。这是我的尝试。

主功能

        //Fileinfo object wraps the file path.
        var hymns = new FileInfo(@"C:HymnWords.txt");

        //StreamReader reads from the existing file.
        var reader = hymns.OpenText();

        string line;
        int number = 0;
        var hymns = new List<Hymn>();

        var check = false; //this is set to indicate that all the lines that are follwoing will be apart of the hymn.

        while ((line = reader.ReadLine())!=null)
        {
                if (line.Any(char.IsLetter) && line.Any(char.IsDigit))
                {

                }

                if (check)
                {
                    if (line.Any(c => char.IsDigit(c) && c != 0) && !line.Any(char.IsLetter))
                    {

                    }

                }


            }

赞美诗的模型

public class Hymn
{
    public string Name { set; get; }
    public List<String> Verses { set; get; }
}

储存经文时。我需要保留换行符。正在插入一个

/n

在将经文插入对象或数据库之前的每一行之后,这样做的最佳方法是什么?

4

3 回答 3

3

这应该可以让您很好地开始:

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

namespace Program
{
    public class Class1
    {
        public class Program
        {
            public static void Main(string[] args)
            {
                var hymnFiles = new List<string>()
                {
                    @"C:\HymnWords.txt",
                    @"C:\HymnWords1.txt",
                    @"C:\HymnWords2.txt",
                    @"C:\HymnWords3.txt",
                };
                var reader = new Class1();
                foreach (var hymn in reader.ReadHymnFiles(hymnFiles))
                {
                    Console.Out.WriteLine(hymn.Title);
                    foreach (var verse in hymn.Verses)
                    {
                        Console.Out.WriteLine(verse.VerseNumber);
                        foreach (var verseLine in verse.VerseLines)
                        {
                            Console.Out.WriteLine(verseLine);
                        }
                    }
                }
                Console.ReadLine();
            }

        }
        public List<Hymn> ReadHymnFiles(List<string> hymnFiles)
        {
            var hymns = new List<Hymn>();
            foreach (var hymnFile in hymnFiles)
            {
                using (TextReader reader = new StreamReader(hymnFile))
                {
                    var hymn = new Hymn();
                    hymns.Add(hymn);
                    string line;
                    int currentVerseNumber = 0;
                    while ((line = reader.ReadLine()) != null)
                    {
                        if (string.IsNullOrWhiteSpace(line))
                            continue;

                        if (line.Any(char.IsLetter) && line.Any(char.IsDigit))
                        {
                            // this must be the title
                            hymn.Title = line;
                            continue;
                        }

                        if (line.Any(c => char.IsDigit(c) && c != 0) && !line.Any(char.IsLetter))
                        {
                            //this must be the verse number
                            currentVerseNumber = Convert.ToInt32(line.Trim());
                            hymn.Verses.Add(new Verse(currentVerseNumber));
                            continue;
                        }

                        //get the current verse to add the next line to it
                        var verse = hymn.Verses.Single(v => v.VerseNumber == currentVerseNumber);
                        verse.VerseLines.Add(line);
                    }
                }
            }
            return hymns;
        }

        public class Hymn
        {
            public Hymn()
            {
                Verses = new List<Verse>();
            }
            public string Title { set; get; }
            public List<Verse> Verses { set; get; }
        }

        public class Verse
        {
            public Verse(int verseNumber)
            {
                VerseNumber = verseNumber;
                VerseLines = new List<string>();
            }
            public int VerseNumber { get; private set; }
            public List<string> VerseLines { set; get; }
        }
    }

}

请注意,这些经文是在他们自己的对象中,每一行都是它自己的行。它们可能也应该以这种方式存储。

于 2013-03-23T20:32:49.483 回答
3

这可能会有所帮助,但您可能需要更多的异常处理。
我稍微更改了您的 Hymn 课程,以使其更易于使用。

这是修改后的赞美诗类:

public class Hymn
{
    private readonly List<List<string>> _verses = new List<List<string>>();

    public Hymn(string name)
    {
        Name = name;
    }

    public string Name { get; private set; }
    public IEnumerable<IEnumerable<string>> Verses { get { return _verses; } }

    public List<string> CreateVerse()
    {
        var verse = new List<string>();
        _verses.Add(verse);
        return verse;
    }
}

这是一个从文件中读取赞美诗的类:

public static class HymnReader
{
    public static IEnumerable<Hymn> ReadHymns(string file)
    {
        var lines = File.ReadAllLines(file);
        var hymns = new List<Hymn>();
        Hymn hymn = null;
        List<string> verse = null;
        foreach (var line in lines)
        {
            string text;
            switch (ParseLine(line, out text))
            {
                case LineType.Title:
                    hymn = new Hymn(text);
                    hymns.Add(hymn);
                    break;
                case LineType.Verse:
                    if (verse == null) verse = hymn.CreateVerse();
                    verse.Add(text);
                    break;
                default:
                    verse = null;
                    break;
            }
        }
        return hymns;
    }

    private static LineType ParseLine(string line, out string text)
    {
        text = "";
        if (string.IsNullOrWhiteSpace(line)) return LineType.Unkown;
        var array = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
        if (array.Length < 2) return LineType.Unkown; 
        int n;
        if (int.TryParse(array[0], out n))
        {
            text = string.Join(" ", array, 1, array.Length - 1).Trim();
            return LineType.Title;
        }
        text = string.Join(" ", array).Trim();
        return LineType.Verse;
    }

    private enum LineType
    {
        Unkown,
        Title,
        Verse
    }
}
于 2013-03-23T21:49:57.247 回答
2

这是我在 Shawn McLean 的帮助下得出的最终解决方案。

namespace HymmParser
{
class Program
{
    const string TITLE_REGEX = @"\s*\d+\s{2,}[a-zA-Z]+";

    static void Main(string[] args)
    {
        var hymns = new List<Hymn>();
        //read the file
        string[] lines = System.IO.File.ReadAllLines(@"C:\HymnWords.txt");

        for (int i = 0; i < lines.Count(); i++)
        {
            //regex to check for a white space, a number, 2 or more white spaces then words after.
            if (Regex.IsMatch(lines[i], TITLE_REGEX))
            {
                var hymn = new Hymn
                {
                    //TODO: Add your title parse logic here.
                    Title = lines[i]
                };

                //find verses under this hymn
                for (i++; i < lines.Count(); i++)
                {
                    //ensure this line is not a title, else break out of it.
                    if (Regex.IsMatch(lines[i], TITLE_REGEX))
                    {
                        break;
                    }

                    //if number only found, this is the start of a verse
                    if (Regex.IsMatch(lines[i], @"^\s*\d+$"))
                    {
                        var verse = new Verse(int.Parse(lines[i]));

                        //gather up verse lines
                        for (i++; i < lines.Count(); i++)
                        {
                            //if number only, break.
                            if (Regex.IsMatch(lines[i], @"\s*\d+"))
                            {
                                //backup and break, outer loop will increment and miss this new verse
                                i--;
                                break;
                            }
                            else if (string.IsNullOrWhiteSpace(lines[i]))
                            {
                                //if whitespace, then we may have finished the verse, break out
                                break;
                            }
                            else
                            {
                                verse.VerseLines.Add(lines[i]);
                            }
                        }
                        hymn.Verses.Add(verse);
                    }
                }
                hymns.Add(hymn);
            }
        }
        foreach (var hymn in hymns)
        {
            Console.WriteLine(hymn.Title);
            foreach (var verse in hymn.Verses)
            {
                Console.WriteLine(verse.VerseNumber);
                foreach (var line in verse.VerseLines)
                {
                    Console.WriteLine(line);
                }
            }
            Console.WriteLine("\n");
        }

        Console.WriteLine("Hymns Found: {0}", hymns.Count);

        Console.ReadLine();

    }
}

public class Hymn
{
    public Hymn()
    {
        Verses = new List<Verse>();
    }
    public string Title { set; get; }
    public List<Verse> Verses { set; get; }
}

public class Verse
{
    public Verse(int verseNumber)
    {
        VerseNumber = verseNumber;
        VerseLines = new List<string>();
    }
    public int VerseNumber { get; private set; }
    public List<string> VerseLines { set; get; }
}

}

于 2013-03-24T00:15:52.090 回答