【问题标题】:C# get text from file between two hashesC#从两个哈希之间的文件中获取文本
【发布时间】:2012-05-28 19:43:06
【问题描述】:

在我的 C# 程序中(此时)我的表单中有两个字段。一种是使用列表框的单词列表;另一个是文本框。我已经能够成功地将一个大单词列表从文本文件加载到列表框中。我也可以通过这种方式将列表框中的选定项目显示到文本框中:

private void wordList_SelectedIndexChanged(object sender, EventArgs e)
     {
          string word = wordList.Text;
          concordanceDisplay.Text = word;
     }

我需要访问另一个本地文件,以便在文本框中显示其中的一些内容。在这个文件中,每个词条(如字典中的)前面都有一个#。所以,我想使用变量“word”并在这个本地文件中搜索以将条目放入文本框中,如下所示:

#headword1
    entry is here...
    ...
    ...
#headword2
    entry is here...
    ...
    ...
#headword3
    entry is here...
    ...
    ...

你得到文本文件的格式。我只需要在该词之前用# 搜索正确的词条,然后从那里复制所有信息,直到文件中的下一个哈希值,并将其放在文本框中。

显然,我是新手,所以要温柔。非常感谢。

附:我使用 StreamReader 获取单词列表并将其显示在列表框中,如下所示:

StreamReader sr = new StreamReader("C:\\...\\list-final.txt");
       string line;
       while ((line = sr.ReadLine()) != null)
       {
           MyList.Add(line);
       }
       wordList.DataSource = MyList;

【问题讨论】:

  • 你的大词表有多大?是不是一下子就全部塞进了记忆里?

标签: c# streamreader


【解决方案1】:
var sectionLines = File.ReadAllLines(fileName) // shortcut to read all lines from file
    .SkipWhile(l => l != "#headword2") // skip everything before the heading you want
    .Skip(1) // skip the heading itself
    .TakeWhile(l => !l.StartsWith("#")) // grab stuff until the next heading or the end
    .ToList(); // optional convert to list

【讨论】:

    【解决方案2】:
    string getSection(string sectionName)
    {
        StreamReader sr = new StreamReader(@"C:\Path\To\file.txt");
        string line;
        var MyList = new List<string>();
        bool inCorrectSection = false;
        while ((line = sr.ReadLine()) != null)
        {
            if (line.StartsWith("#"))
            {
                if (inCorrectSection)
                    break;
                else
                    inCorrectSection = Regex.IsMatch(line, @"^#" + sectionName + @"($| -)");
            }
            else if (inCorrectSection)
                MyList.Add(line);
        }
        return string.Join(Environment.NewLine, MyList);
    }
    
    // in another method
    textBox.Text = getSection("headword1");
    

    以下是检查部分是否匹配的几种替代方法,粗略的顺序是它们检测正确部分名称的准确度:

    // if the separator after the section name is always " -", this is the best way I've thought of, since it will work regardless of what's in the sectionName
    inCorrectSection = Regex.IsMatch(line, @"^#" + sectionName + @"($| -)");
    // as long as the section name can't contain # or spaces, this will work
    inCorrectSection = line.Split('#', ' ')[1] == sectionName;
    // as long as only alphanumeric characters can ever make up the section name, this is good
    inCorrectSection = Regex.IsMatch(line, @"^#" + sectionName + @"\b");
    // the problem with this is that if you are searching for "head", it will find "headOther" and think it's a match
    inCorrectSection = line.StartsWith("#" + sectionName);
    

    【讨论】:

    • 不要在每一行上调用子字符串,为什么不只寻找“#”+ word :) 也可以使用 line.Equals("#" + word, StringComparison.CurrentCultureIgnoreCase) 代替。最后我会索引字典文件以便更快地查找。
    • 我只在 # 行调用 substring。无论哪种方式,您都可以这样做,使用子字符串只是我想到的第一个。如果提问者想要 CurrentCultureIgnoreCase 比较,这是一个很好的方法。
    • 感谢您的帮助。我在这里很困惑:inCorrectSection = line.Substring(1) == sectionName;。看来您正在将子字符串值应用于变量inCorrectSection,它是布尔值。我一定是错过了什么。
    • 也可以写成inCorrectSection = (line.Substring(1) == sectionName);。也就是说,我将line 在它的第一个字符之后与sectionName 进行比较。结果是一个布尔值,然后我将其存储在inCorrectSection
    • inCorrectSection = (line.Substring(1) == sectionName);这可能更清楚。括号是该行与您要查找的单词之间的比较。它是一个布尔值,然后会影响 isCorrectSection。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-20
    • 2019-05-29
    • 1970-01-01
    • 1970-01-01
    • 2015-06-07
    • 1970-01-01
    相关资源
    最近更新 更多