过滤类字符串属性

时间:2017-10-11 07:02:39

标签: c# regex linq

我希望以任何顺序过滤类User字符串属性。

我的internal class User { public string FirstName { get; } public string LastName { get; } public string Email { get; } public User(string firstName, string lastName, string email) { FirstName = firstName; LastName = lastName; Email = email; } public override string ToString() { return $"{FirstName} {LastName} - {Email}"; } } 课程如下:

    private readonly List<User> _userList = new List<User>();

    public Form1()
    {
        InitializeComponent();

        _userList.Add(new User("Zar", "Nikolaus II", "ruler@stackoverflow.bom"));
        _userList.Add(new User("Tommy", "Hilfiger", "polo@stackoverflow.bom"));
        _userList.Add(new User("Nina", "Richy", "thin-thing@stackoverflow.bom"));
        _userList.Add(new User("Armin", "Van Buren", "singer@stackoverflow.bom"));
        _userList.Add(new User("Lauren", "Ralph", "polo@stackoverflow.bom"));
        _userList.Add(new User("Van der Vaart", "(Marin-) Rafael", "soccer@stackoverflow.bom"));
        _userList.Add(new User("Tommy", "Vercetti", "character@stackoverflow.bom"));
    }

    private void FilterIt()
    {
        var filter = textBox1.Text;
        var properties = typeof(User).GetProperties();
        var filteredUsers = this._userList.Where(user => properties.Any(propInfo => Regex.Split(propInfo.GetValue(user).ToString(), @"\W").Any(w => filter.Contains(w))));
    }

我的过滤算法如下所示:

{{1}}

现在我的目标是使用以下过滤器获得以下结果:

过滤:Tom

  1. Tom 我的Hilfiger - polo@stackoverflow.bom
  2. 汤姆我的Vercetti - character@stackoverflow.bom
  3. 过滤器:面包车

    1. Van der Vaart(Marin-)Rafael - soccer@stackoverflow.bom
    2. Armin Van Buren - singer@stackoverflow.bom
    3. 过滤:rafa va

      1. Va n der Va 艺术(Marin-) Rafa el - soccer@stackoverflow.bom
      2. Armin Va n Buren - singer@stackoverflow.bom
      3. 过滤:ra

        1. Lauren Ra lph - polo@stackoverflow.bom
        2. Van der Vaart(马林 - ) Ra fael - soccer@stackoverflow.bom
        3. Tommy Vercetti - cha ra cter@stackoverflow.bom

1 个答案:

答案 0 :(得分:1)

似乎唯一的诀窍是在匹配时放置ToString() - FirstNameLastNameEmail组合:

string filter = "rafa va";

// We assume that 
//   1. Patterns are separated by space (or tabulation)
//   2. Patterns should be matched in any order 
//   3. Case should be ignored 
var patterns = filter
  .Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries)
  .Select(item => Regex.Escape(item)) // <- comment it out if you want to allow, say, \d+ 
  .ToArray();

var result = _userList
  .Where(user => patterns
     .All(pattern => Regex.IsMatch(user.ToString(), pattern, RegexOptions.IgnoreCase)));