Uni Le
Uni Le

Reputation: 793

Read Text File from specific places

I have a question about read a text file, because i dont know if i'm thinking right. I want to read from specific string to specific character.

My text would look like this:

... 
...
CM_ "Hello, how are you?

Rules: Don't smoke!
      - love others

End";
...
CM_ "Why you?";
...// Many CM_
...

After Splited should look like that:

1. CM_
2. "Hello, how are you?

    Rules: Don't smoke!
      - love others

    End"
3. CM_
4. "Why you?"
... // many CM_

I want to read from "CM_" till ";"

My Code i tried so far:

StreamReader fin = new StreamReader("text.txt");
string tmp = "";
tmp = fin.ReadToEnd();

if (tmp.StartsWith("CM_ ") && tmp.EndWith(";"))
{
var result = tmp.Split(new[] { '"' }).SelectMany((s, i) =>
                    {
                        if (i % 2 == 1) return new[] { s };
                        return s.Split(new[] { ' ', ';' }, StringSplitOptions.RemoveEmptyEntries);
                    }).ToList();
}
foreach (string x in result)
{
   Console.WriteLine(x);
}

Upvotes: 0

Views: 972

Answers (5)

svinja
svinja

Reputation: 5576

    static void PRegex()
    {
        using (StreamReader fin = new StreamReader("text.txt"))
        {
            string tmp = fin.ReadToEnd();

            var matches = Regex.Matches(tmp, "(CM_) ([^;]*);", RegexOptions.Singleline);
            for (int i = 0; i < matches.Count; i++)
                if (matches[i].Groups.Count == 3)
                    Console.WriteLine((2 * i + 1).ToString() + ". " + matches[i].Groups[1].Value + "\r\n" + (2 * (i + 1)).ToString() + ". " + matches[i].Groups[2].Value);
        }

        Console.ReadLine();
    }

    static void PLineByLine()
    {
        using (StreamReader fin = new StreamReader("text.txt"))
        {
            int index = 0;
            string line = null;
            string currentCMBlock = null;
            bool endOfBlock = true;
            while ((line = fin.ReadLine()) != null)
            {
                bool endOfLine = false;
                while (!endOfLine)
                {
                    if (endOfBlock)
                    {
                        int startIndex = line.IndexOf("CM_ ");
                        if (startIndex == -1)
                        {
                            endOfLine = true;
                            continue;
                        }
                        line = line.Substring(startIndex + 4, line.Length - startIndex - 4);
                        endOfBlock = false;
                    }

                    if (!endOfBlock)
                    {
                        int startIndex = line.IndexOf(";");
                        if (startIndex == -1)
                        {
                            currentCMBlock += line + "\r\n";
                            endOfLine = true;
                            continue;
                        }
                        currentCMBlock += line.Substring(0, startIndex);
                        if (!string.IsNullOrEmpty(currentCMBlock))
                            Console.WriteLine((++index) + ". CM_\r\n" + (++index) + ". " + currentCMBlock);
                        currentCMBlock = null;
                        line = line.Substring(startIndex + 1, line.Length - startIndex - 1);
                        endOfBlock = true;
                    }
                }
            }
        }

        Console.ReadLine();
    }

Upvotes: 1

Stonehead
Stonehead

Reputation: 376

I suggest you look into using Regular Expressions. It may be just what you need and much more flexible than Split().

Upvotes: 0

Uni Le
Uni Le

Reputation: 793

I tried something else, don't know if this is good. It still read the first Line, dont know that i did wrong here

my Code:

        while ((tmp = fin.ReadLine()) != null)
        {
            if (tmp.StartsWith("CM_ "))
            {

                //string[] tmpList = tmp.Split(new Char[] { ' ', ';' }, StringSplitOptions.RemoveEmptyEntries);
                var result = tmp.Split(new[] { '"' }).SelectMany((s, i) =>
                {
                    if (i % 2 == 1) return new[] { s };
                    return s.Split(new[] { ' ', ';' }, StringSplitOptions.RemoveEmptyEntries);
                }).ToList();

                if (tmp.EndsWith(";")) break;

                fin.ReadLine();

                if (tmp.EndsWith(";"))
                {
                    result.ToList();
                    break;
                }
                else
                {
                    result.ToList();
                    fin.ReadLine();
                }

                foreach (string x in result)
                {
                    Console.WriteLine(x);
                }
            } 

Upvotes: 0

GhostHax
GhostHax

Reputation: 33

Read the whole file:

string FileToRead = File.ReadAllText("Path");

string GetContent(string StartAt, string EndAt, bool LastIndex)
{
string ReturnVal;

if(LastIndex)
{
ReturnVal = FileToRead.Remove(FileToRead.IndexOf(StartAt), FileToRead.IndexOf(EndAt));
Return ReturnVal;
}
else
{ 
ReturnVal = FileToRead.Remove(FileToRead.LastIndex(StartAt), FileToRead.LastIndex(EndAt));
Return ReturnVal;
}
}

-Hope I didn't do anything wrong here. (Free mind typing)

You read the file, and we remove all the content, infront of the first index. and all after it. You can set it if will return the FIRST result found. or the last.

NOTE: I think it would be better to use a StringReader. (If I don't remember wrong...) If you are to think about the memory usage of your application.

Upvotes: 0

Justin Harvey
Justin Harvey

Reputation: 14682

You are reading the whole file into tmp. So, if there is any text before "CM_" then your conditional statement won't be entered.

Instead, try reading line by line with fin.ReadLine in a loop over all lines.

Upvotes: 0

Related Questions