Click here to Skip to main content
15,881,172 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have a text file where I am looking for a word however I need the word prior to one I am searching for. For example "Patrick Called". The common word that I would search for is Called, but I want to return Patrick. I am currently using Streamreader but am stuck
Posted
Updated 11-Jan-14 10:39am
v2

Try this:
C#
string fileText = File.ReadAllText("yourFile.txt");
string[] words = fileText.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); // this splits the string and makes sure that there are no empty strings in the array
int wordIndex = Array.IndexOf(words, "Called");
if (wordIndex > 0)
{
    string str = words[wordIndex - 1];
    Console.WriteLine(str); // this will print 'Patrick' if the file contains 'Patrick Called'
}
else
{
    // the searched word is the first word; you can't get the word before it
    // OR: the searched word doesn't exist
}

Hope this helps.
 
Share this answer
 
v4
Comments
CPallini 11-Jan-14 15:17pm    
5.
Thomas Daniels 12-Jan-14 8:44am    
Thank you!
Karthik_Mahalingam 11-Jan-14 21:42pm    
5!
Thomas Daniels 12-Jan-14 8:44am    
Thank you!
JayantaChatterjee 11-Jan-14 22:31pm    
My vote of 5..
HI On top of ProgramFox solution.
try this using StreamReader , this will read all the names matching the defined word..

C#
class Program
   {
       static void Main(string[] args)
       { //ƒ
           string file = @"D:\Projects\console_poc\console_poc\text.txt";
           // input as below
           //Patrik Called something.. john Called
           //some test test test karthik Called .....

           using (StreamReader sr = new StreamReader(file))
           {
               String line = sr.ReadToEnd();
               string[] array = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
               string key = "Called";
               for (int i = 1; i < array.Length; i++)
               {
                   if (array[i] == key)
                       Console.WriteLine(array[i - 1]);
                   // output as below:
                   // Patrik
                   // john
                   // karthik
               }
           }

           Console.ReadLine();


       }
   }
 
Share this answer
 
Comments
BillWoodruff 11-Jan-14 22:03pm    
+4 I think this is the type of solution that is required, but what is also ... possibly ... needed is to handle the case where the target search string is at the beginning of a line, and you need to return the word at the end of the previous line. Handle that case and you have your 5 :)
Karthik_Mahalingam 11-Jan-14 22:35pm    
Thanks :)
Bill, to avoid that case i have used index as 1 ( int i = 1 ). Please check it :)
Maurader 11-Jan-14 23:04pm    
This worked well, however I noticed that Called is actually Called! and does not return a result if the ! is there.
Karthik_Mahalingam 11-Jan-14 23:06pm    
then you can replace the line if (array[i] == key) by if (array[i].Contains( key))
Thomas Daniels 12-Jan-14 8:46am    
+5! It is a good idea to use int i = 1 to avoid IndexOutOfRangeExceptions.
This is an add on for solution one.

fileText.Split(new char[] { ' ', '\n', '.' }

When the word is on the end of the line the split with a space wont work. So also add '\n'.
 
Share this answer
 
Assuming:

1. there may be more than one match present in the file

1.a. it is necessary to find all matches

2. it is better practice to read the file line-by-line ... you might wish to halt reading the file when you've found a match (?), or, the file may be quite large (?)

3. a goal is to minimize "high cost" operations like calling 'Split on a string.

4. it is more probable the word preceding the match occurs within the line rather than at the end of the line.

C#
// required in addition to the usual Win Forms references
using System.IO;
using System.Collections.Generic;
using System.Linq;

private char[] splitChar = new char[] {' '};
private int matchLength;
private int matchIndex;

private void ScanFileForMatches(string filePath, string matchMarker)
{
    string[] splitLine = null;
    string currentLine = null;
    string previousLine = null;
    string matchString = null;

    matchLength = matchMarker.Length;

    using (StreamReader sr = new StreamReader(filePath))
    {
        while (! sr.EndOfStream)
        {
            currentLine = sr.ReadLine();

            if (currentLine.Contains(matchMarker))
            {
                // simple case: match and preceding word
                // are on the same line
                if (matchMarker != currentLine.Substring(0, matchLength))
                {
                    splitLine = currentLine.Split(splitChar);
                    matchIndex = Array.FindIndex(splitLine, str => str == matchMarker) - 1;
                }
                else if (previousLine != null)
                {
                    // match at last word in the previous line
                    splitLine = previousLine.Split(splitChar);
                    matchIndex = splitLine.Count() - 1;
                }

                matchString = splitLine[matchIndex];

                Console.WriteLine("word before match: {0} position of word before match in line: {1}",matchString, matchIndex);
            }
            previousLine = currentLine;
        }
    }
}
Disclaimer:

1. I've tested this with the following text file, and a match-marker string, "called:"

Quote:
once upon a time
the man named Patrick
called the pest-control operator;
and he kept talking
until Maria called
and, so forth and so on,
but, then, David called to say
that
If he ever called Maria again,
that she would say she never called
him back.
And, it correctly handled all cases. However, be advised this is extracted from some code written years ago, and adapted quickly, for educational purposes, and you should test this thoroughly before using it in production code. I take no responsibility for performance of this code. If you find a bug in it, of course I'd like to know !

Possible to-do's:

1. an obvious omission here is testing for when the match-marker string might have a punctuation mark added to it: "called." "called," ... etc.

2. how about making the search work for any variation of upper- or lower- case match-marker string ?

3. what if the marker-string is the first word in the file ? Throw an error ?
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900