在线搜索关键字并打印该行和以下行

时间:2016-04-09 20:59:36

标签: c#

我使用以下方法来解析文本文件并编写包含特定关键字的行:

using (StreamReader sr = new StreamReader("C:/Users/Downloads/apple.txt"))
        {
            string appleLine;
            bool lastLine = false;
            // currentLine will be null when the StreamReader reaches the end of file
            while ((appleLine = sr.ReadLine()) != null)
            {
                // Search, case insensitive, if the currentLine contains the searched keyword
                if (appleLine.IndexOf("Apple", StringComparison.CurrentCultureIgnoreCase) >= 0 || lastLine)
                {
                    Console.WriteLine(appleLine);
                    Console.WriteLine();
                    using (System.IO.StreamWriter file = new System.IO.StreamWriter(@"C:\Users\Downloads\parsed.txt", true))
                    {
                        file.WriteLine(appleLine);
                        file.WriteLine();
                    }
                    lastLine = true;
                }

                if (lastLine)
                {
                    lastLine = false;
                }
            }

在apple.txt中,我有类似的东西:

--- Line1 Apple MacBook Pro ---

--- Line2 www.newegg.com ---

但这不会打印带有URL的行(第2行)。 apple.txt文件可能有200行。

非常感谢您的帮助!

3 个答案:

答案 0 :(得分:0)

您可以尝试使用一个布尔值来指示'当前行'已打印,然后打印下一行后打破循环。这样不仅会打印currentLine,还会打印下一行,之后将退出while循环。

using (StreamReader sr = new StreamReader("c:/temp/ESMDLOG.csv"))
{
    string currentLine;
    **bool lastline = false;**

    // currentLine will be null when the StreamReader reaches the end of file
    while((currentLine = sr.ReadLine()) != null)
    {
        // Search, case insensitive, if the currentLine contains the searched keyword
        if(currentLine.IndexOf("I/RPTGEN", StringComparison.CurrentCultureIgnoreCase) >= 0 **|| lastline**)
        {
             Console.WriteLine(currentLine);
             lastline = true;
        }

        **//Optional, could also say lastline = false inside if, in case you want to keep looping after printing**
        **if(lastline){
              break;
        }**
    }
}

答案 1 :(得分:0)

如果没有更精确的问题陈述,就无法确定您想要的输出。但是到目前为止,类似以下的内容将达到目标:

using (StreamReader sr = new StreamReader("c:/temp/ESMDLOG.csv"))
{
    bool printWindow = false;
    Queue<string> window = new Queue<string>();
    string currentLine;
    // currentLine will be null when the StreamReader reaches the end of file
    while((currentLine = sr.ReadLine()) != null)
    {
        bool nextPrintWindow = false

        // Search, case insensitive, if the currentLine contains the searched keyword
        if(currentLine.IndexOf("I/RPTGEN", StringComparison.CurrentCultureIgnoreCase) >= 0)
        {
             nextPrintWindow = true;
        }

        if (window.Count >= 3)
        {
            window.Dequeue();
        }

        window.Enqueue(currentLine);

        if (printWindow)
        {
            Console.WriteLine(string.Join(Environment.NewLine, window));
        }

        printWindow = nextPrintWindow;
    }
}

(警告:上面的浏览器代码。请原谅错别字和其他疏忽。)

上面保留了一个window集合,即一个三行&#34;窗口&#34;文件中的文本,通过排队当前行,如果集合达到三个元素的计数,则将最旧的行出列。

同时,它保持一个标志,指示在读取下一行后是否打印窗口内容。如果此标志设置为true,它会将window集合中的行与换行符连接起来并打印出整个内容。

这样,如果当前行符合您的匹配条件,则会打印当前行以及前一行和下一行。

请注意,上面将为每场比赛打印三行窗口。例如,如果连续的线符合匹配标准,则可以多次打印线(作为不同的三线组的一部分)。如果连续的行满足匹配条件,则可以使用另一种实现方式使窗口增长超过三个元素,只有在读取了不符合匹配条件的行时才打印(并重新启动)窗口。

另一种替代方案是在打印窗口之前需要两个不匹配的行,即如果你想确保即使不匹配的行只打印一次。

我将这些变化作为练习留给读者。它们与上面的内容没有太大区别,只是对窗口维护的微小变化以及封装在标志变量中的隐含状态机的管理。

答案 2 :(得分:0)

尝试使用一个布尔值,显示您要找到要打印的内容,并且还需要打印下一行。例如:

class Program
{
    static void Main(string[] args)
    {
        bool nextLineToPrint = false;
        using (StreamReader sr = new StreamReader("c:/temp/ESMDLOG.csv"))
        {
            string currentLine;
            // currentLine will be null when the StreamReader reaches the end of file
            while ((currentLine = sr.ReadLine()) != null)
            {
                if (nextLineToPrint)
                {
                    Console.WriteLine(currentLine);
                    nextLineToPrint = false;
                }
                // Search, case insensitive, if the currentLine contains the searched keyword
                if (currentLine.IndexOf("I/RPTGEN", StringComparison.CurrentCultureIgnoreCase) >= 0)
                {
                    Console.WriteLine(currentLine);
                    nextLineToPrint = true;
                }
            }
        }
        Console.ReadLine();
    }
}