1

我必须解析一个像这样构造的文件:

User: jcruz Name: Jules Last: Cruz  Email: Some@email.com 
User: jdoe Name: John Last: Doe Email: Some@email.com 
User: pmartin Name: Pete Last: Martin Email: Some@email.com 
User: rrichard Name: Reed Last: Richard Email: Some@email.com

我需要将仅包含姓名、姓氏和电子邮件的每一行拆分为类型的对象

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

所以我的问题是使用哪个工具 :String.SplitRegex.Split. 以及如何实施。

非常感谢你...

这是迄今为止所做的:

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...


            }

        }
4

4 回答 4

3
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();
于 2012-09-05T16:50:18.027 回答
1

试试这个:

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] });
            }
        }
于 2012-09-05T16:58:01.057 回答
0

正则表达式是矫枉过正。还要注意一些包含空格的姓氏。

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();
于 2012-09-05T16:47:16.947 回答
0

答:都没有。

使用简单的有限状态机解析器来读取文件,因为除非您能保证文本值永远不会是“Name:”或“Last:”或“Email:”,否则您将遇到字符串拆分问题。此外,基于 FSM 的解析器比字符串拆分要快得多(因为没有多余的字符串分配)。

我没有时间写出整个解析器,但这是简单的逻辑:

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...
    }
}

当然,FSM 解析器与正则表达式解析器本质上是一样的,但这意味着您可以自己编写状态转换代码,而不是使用更快、性能更佳的 RegEx 语法。

如果您的项目很小并且不关心性能,并且可以保证某些数据格式规则,那么我会使用正则表达式。

但是永远不要使用 String.Split 来读取文件。

于 2012-09-05T16:47:34.360 回答