Jose M. Vilomar
Jose M. Vilomar

Reputation: 487

Parse file with multiples values lines C#

I have to parse a file that is constructed like this :

User: jcruz Name: Jules Last: Cruz  Email: [email protected] 
User: jdoe Name: John Last: Doe Email: [email protected] 
User: pmartin Name: Pete Last: Martin Email: [email protected] 
User: rrichard Name: Reed Last: Richard Email: [email protected]

I need to split every line taking just Name, Last Name and Email into an object of the type

var contact = new Conctact {
    Name = fieldFromLine,
    Last= fieldFromLine,
    Email = fieldFromLine
}

So my problem is which tool use : String.Split or Regex.Split. and how to implement it.

Thank you very much...

This is what a Have done so far:

String archivo = ((FileDialog)sender).FileName;

        using (TextReader sr = new StreamReader(archivo,Encoding.UTF8))
        {
            String line = String.Empty;
            while ((line = sr.ReadLine()) != null )
            {
                string[] result = Regex.Split(line,"User:");
                //How to get the other fields...


            }

        }

Upvotes: 1

Views: 177

Answers (4)

KF2
KF2

Reputation: 10153

try this:

public class  contact 
{
   public string Name { get; set; }
   public string Lname { get; set; }
   public string Email { get; set; }
}
List<contact> contact = new List<contact>();
        private void split()
        {
            var lines = File.ReadAllLines(@"txt file address");
            foreach (var line in lines)
            {
               var splitline=line.Split(':');
           string name = splitline[2].Replace("Last", "");
           string lname = splitline[3].Replace("Email","");
           contact.Add(new contact { Name = name, Lname = lname, Email = splitline[4] });
            }
        }

Upvotes: 1

egrunin
egrunin

Reputation: 25053

Regex is overkill. Also note that some last names that contain spaces.

Contact c = new Contact();
string () tokens = input.Split(":".ToCharArray());

if (tokens.Count < 5)
    return; // error

// now strip the last word from each token
c.Name = tokens(2).Substring(0, tokens(2).LastIndexOf(" ".ToCharArray())).Trim();
c.Last = tokens(3).Substring(0, tokens(3).LastIndexOf(" ".ToCharArray())).Trim();
c.Email = tokens(4).Trim();

Upvotes: 0

L.B
L.B

Reputation: 116118

var result =File.ReadLines(fileName)
    .Select(line => line.Split(new string[]{"User:", "Name:", "Last:", "Email:"}, StringSplitOptions.RemoveEmptyEntries))
    .Select(parts => new Conctact(){ Name = parts[1], Last = parts[2], Email = parts[3] })
    .ToArray();

Upvotes: 3

Dai
Dai

Reputation: 155145

Answer: neither.

Use a simple finite-state machine parser to read the file because unless you can guarantee that the text values will never be "Name:" or "Last:" or "Email:" then you'll run into problems with string splitting. Also FSM-based parsers are significantly faster than string splitting (as there is no extraneous string allocation).

I don't have the time to write out an entire parser, but here's the simple logic:

enum State { InUser, InName, InLast, InEmail }

State currentState = State.InUser; // you start off with the 'cursor' in the "User" section
StringBuilder sb = new StringBuilder(); // this holds the current string element
foreach(Char c in entireTextFile) { // presumably using `StreamReader.Read()`
    switch( currentState ) {
        case InUser:
             switch( c ) {
                 // state transition logic here
             }
             // append the character to the StringBuilder until you've identified and reached the next field, then save the sb value to the appropriat
        case InName:
             // and so on...
    }
}

Of course, an FSM parser is fundamentally the same thing as a Regular Expression parser, but it means you get to code the state-transitions yourself rather than using RegEx's syntax which is faster, performance-wise.

If your project is small and don't care about performance, and can guarantee certain data formatting rules then I'd go with regex.

But never, ever, use String.Split to read a file.

Upvotes: 0

Related Questions