C# 在字符串中查找值

C# 在字符串中查找值,c#,.net,.net-3.5,C#,.net,.net 3.5,我有一个有几行字符串的文件。每行表示键值的集合,例如: Name=JUI;Type=HomeUser;Address=Belgium;Address=Liege;Address=Street Name=Tim;Type=HomeUser;Address=Belgium;Address=Hasselt;Address=Street Name=Kim;Type=Proff;Address=Germany;Address=Dusseldorf;Address=Street Name=Ils;Type=

我有一个有几行字符串的文件。每行表示键值的集合,例如:

Name=JUI;Type=HomeUser;Address=Belgium;Address=Liege;Address=Street
Name=Tim;Type=HomeUser;Address=Belgium;Address=Hasselt;Address=Street
Name=Kim;Type=Proff;Address=Germany;Address=Dusseldorf;Address=Street
Name=Ils;Type=Proff;Address=Germany;Address=Munich;Address=Street
Name=Jan;Type=Student;Address=Germany;Address=Frankfurt;Address=Street
Name=Dav;Type=Student;Address=France;Address=Mitz;Address=Street
Name=Soli;Type=HomeUser;Address=France;Address=Lyon;Address=Street
Name=Mik;Type=HomeUser;Address=Switzerland;Address=Zurich;Address=Street
Name=Peter;Type=Blocked;Address=Netherland;Address=Enschede;Address=Street 
Name=Maz;Type=Blocked;Address=Germany;Address=Achen;Address=Street
Name=Jo;Type=Teacher;Address=Belgium;Address=Antwerpen;Address=Street
我怎样才能做到以下几点:

  • 获取类型为HomeUser的名称
  • 获取Address=Germany的类型(问题是搜索行中有3个地址键)
  • 获取address=Lyon的名称

  • 有一种简单的方法可以做到这一点吗?

    我认为可以使用正则表达式将标记与反向引用相匹配


    看看这个。

    我认为可以使用正则表达式将标记与反向引用匹配

    看看这个。

    在所有这些情况下,当您有更好的数据表示时,答案非常简单-您可以使用LINQ

    然而,第一步将是解析数据。对其进行如下建模:

    public class User // ???
    {
        public string Name { get; private set; }
        public string Type { get; private set; } // Should this be an enum?
        public IList<string> Addresses { get; private set; }
    
        // Could make this a constructor if you really want... I like the
        // explicit nature of the static factory method.
        public static User ParseLine(string line)
        {
            // TODO: Split line into components etc
        }
    }
    
    string tNILF = myStruct.Where(element => element.Type == "HomeUser" /* || etc. */).Select(element => element.Name);
    
    公共类用户//???
    {
    公共字符串名称{get;private set;}
    公共字符串类型{get;private set;}//是否应为枚举?
    公共IList地址{get;private set;}
    //如果你真的想的话,可以把它变成构造函数…我喜欢
    //静态工厂方法的显式性质。
    公共静态用户解析行(字符串行)
    {
    //TODO:将线路拆分为组件等
    }
    }
    
    如果你有一个
    列表
    ,你的查询将非常简单,但将“将数据放入更自然的表示”与“对数据进行有趣的操作”分开是很重要的

    这是一个比这一特定示例更一般的观点,但始终尽可能早地将数据转换为自然、有用的表示形式,然后尽可能长时间地将其保存在该表示形式中。如果可能的话,只处理代码边界处的笨拙表示(通常是字符串)。

    在所有这些情况下,当您有更好的数据表示时,答案非常简单-您可以使用LINQ

    然而,第一步将是解析数据。对其进行如下建模:

    public class User // ???
    {
        public string Name { get; private set; }
        public string Type { get; private set; } // Should this be an enum?
        public IList<string> Addresses { get; private set; }
    
        // Could make this a constructor if you really want... I like the
        // explicit nature of the static factory method.
        public static User ParseLine(string line)
        {
            // TODO: Split line into components etc
        }
    }
    
    string tNILF = myStruct.Where(element => element.Type == "HomeUser" /* || etc. */).Select(element => element.Name);
    
    公共类用户//???
    {
    公共字符串名称{get;private set;}
    公共字符串类型{get;private set;}//是否应为枚举?
    公共IList地址{get;private set;}
    //如果你真的想的话,可以把它变成构造函数…我喜欢
    //静态工厂方法的显式性质。
    公共静态用户解析行(字符串行)
    {
    //TODO:将线路拆分为组件等
    }
    }
    
    如果你有一个
    列表
    ,你的查询将非常简单,但将“将数据放入更自然的表示”与“对数据进行有趣的操作”分开是很重要的


    这是一个比这一特定示例更一般的观点,但始终尽可能早地将数据转换为自然、有用的表示形式,然后尽可能长时间地将其保存在该表示形式中。如果可能的话,只处理代码边界处的笨拙表示(通常是字符串)。

    创建一个正则表达式来解析项:
    “Name=(.+?);Type=(.+?);Address=(.+?)等”
    然后您可以创建一个类来保存所有信息

    class Record { public string Name; public string Type; public string Address; public string Address2; public string Address3}
    
    然后将每一行与正则表达式匹配,填充匹配组中的字段,创建类的实例,并将它们添加到
    列表记录中

    现在,您可以使用linq轻松搜索:

  • 类型为HomeUser:records。其中(p=>p.type==“HomeUser”)
  • 地址是德国:记录。其中(p=>p.Address==“德国”)
  • 地址是里昂:记录。其中(p=>p.Address==“里昂”)

  • 您可以轻松地扩展此示例,查看所有3个地址字段,创建一个正则表达式来解析项:
    “Name=(.+?);Type=(.+?);address=(.+?)等”
    然后您可以创建一个类来保存所有信息

    class Record { public string Name; public string Type; public string Address; public string Address2; public string Address3}
    
    然后将每一行与正则表达式匹配,填充匹配组中的字段,创建类的实例,并将它们添加到
    列表记录中

    现在,您可以使用linq轻松搜索:

  • 类型为HomeUser:records。其中(p=>p.type==“HomeUser”)
  • 地址是德国:记录。其中(p=>p.Address==“德国”)
  • 地址是里昂:记录。其中(p=>p.Address==“里昂”)

  • 您可以很容易地扩展此示例,查看所有3个地址字段

    首先定义一个结构会更容易

    struct MyStruct
    {
        public string Name, Type /* etc.*/ ;
    }
    
    之后,您需要拆分输入

    string[] arrayOfInputs = inpuString.Split(new char[]{Environment.NewLine, '\n', '\r'}) // splits your input, such that every element represents a line
    List<MyStruct> myStruct = new List<MyStruct>;
    foreach (string s in arrayOfInputs)
    {
        string[] arrayOfFields = s.Split(';');
        // arrayOfFields[0] == "Name=name"
        // arrayOfFields[1] == "Type=type"
        // etc. extract needed info
        myStruct.Add(new MyStruct(/* arguments go here */))
    }
    
    或者,您可以这样做:

    public class User // ???
    {
        public string Name { get; private set; }
        public string Type { get; private set; } // Should this be an enum?
        public IList<string> Addresses { get; private set; }
    
        // Could make this a constructor if you really want... I like the
        // explicit nature of the static factory method.
        public static User ParseLine(string line)
        {
            // TODO: Split line into components etc
        }
    }
    
    string tNILF = myStruct.Where(element => element.Type == "HomeUser" /* || etc. */).Select(element => element.Name);
    

    首先定义一个结构会更容易

    struct MyStruct
    {
        public string Name, Type /* etc.*/ ;
    }
    
    之后,您需要拆分输入

    string[] arrayOfInputs = inpuString.Split(new char[]{Environment.NewLine, '\n', '\r'}) // splits your input, such that every element represents a line
    List<MyStruct> myStruct = new List<MyStruct>;
    foreach (string s in arrayOfInputs)
    {
        string[] arrayOfFields = s.Split(';');
        // arrayOfFields[0] == "Name=name"
        // arrayOfFields[1] == "Type=type"
        // etc. extract needed info
        myStruct.Add(new MyStruct(/* arguments go here */))
    }
    
    或者,您可以这样做:

    public class User // ???
    {
        public string Name { get; private set; }
        public string Type { get; private set; } // Should this be an enum?
        public IList<string> Addresses { get; private set; }
    
        // Could make this a constructor if you really want... I like the
        // explicit nature of the static factory method.
        public static User ParseLine(string line)
        {
            // TODO: Split line into components etc
        }
    }
    
    string tNILF = myStruct.Where(element => element.Type == "HomeUser" /* || etc. */).Select(element => element.Name);
    

    一种方法是将键值对读入动态对象的集合中。完成此操作后,可以使用动态运行时使用LINQ查询动态对象:

    要创建动态对象的集合,请执行以下操作:

    var users = str.Split("\r\n".ToArray(), StringSplitOptions.RemoveEmptyEntries)
                    .Select(x => x.Split(';')
                        .Select(p => p.Split('='))
                        .ToLookup(s => s[0], s => s[1])
                        .ToDictionary(l => l.Key, l => (l.Count() > 1) 
                            ? (object)l.ToList() : (object)l.First())
                        .ToExpando());
    
    请注意此扩展方法的使用:

    public static dynamic ToExpando(this IDictionary<string, object> dict)
    {
        IDictionary<string, object> expando = new ExpandoObject();
        foreach (var kv in dict)
            expando[kv.Key] = kv.Value;
        return expando;
    }
    
    2.获取Address=Germany的类型(注意:
    。Address
    是一个
    列表
    ):

    3.获取address=Lyon的名称:

    var namesInLyon = users.Where(u => u.Address.Contains("Lyon"))
        .Select(u => u.Name);
    

    一种方法是将键值对读入动态对象的集合中。完成此操作后,可以使用动态运行时使用LINQ查询动态对象:

    要创建动态对象的集合,请执行以下操作:

    var users = str.Split("\r\n".ToArray(), StringSplitOptions.RemoveEmptyEntries)
                    .Select(x => x.Split(';')
                        .Select(p => p.Split('='))
                        .ToLookup(s => s[0], s => s[1])
                        .ToDictionary(l => l.Key, l => (l.Count() > 1) 
                            ? (object)l.ToList() : (object)l.First())
                        .ToExpando());
    
    请注意此扩展方法的使用:

    public static dynamic ToExpando(this IDictionary<string, object> dict)
    {
        IDictionary<string, object> expando = new ExpandoObject();
        foreach (var kv in dict)
            expando[kv.Key] = kv.Value;
        return expando;
    }
    
    2.获取Address=Germany的类型(注意:
    。Address
    是一个
    列表
    ):

    3.获取address=Lyon的名称:

    var namesInLyon = users.Where(u => u.Address.Contains("Lyon"))
        .Select(u => u.Name);
    

    这里需要的信息远不止一堆作业。这些是字符串、整数、枚举、类吗。。。?这些应该是类的属性吗?在不知道我们在看什么的情况下,绝对没有办法回答这个问题。这些数据是如何被拉进C#并加以利用的?很抱歉,请允许我更简洁地解释一下我的意思。我的意思是,可能有100种或更多不同的方法来解析文件中的数据。我的意思是,如果你想在你的具体案例中找到最好的方法,更多关于数据的信息,数据的去向,以及我在哪里