2012-03-29 104 views
6

所以我有一个物品对象列表。在装备中,我有15个获取和设置方法。我想要构造一个搜索方法来循环列表中的所有对象以及每个Materiel对象中的所有变量。循环部分很容易,但我正在努力与字符串包含部分。例如,搜索词可以是“acto”,我应该对“拖拉机”有所打击。我试过使用string-Contains类,但据我所知,它只检查从0开始的字符串。所以“Tra”得到一个命中,但不是“acto”。c#包含字符串的一部分

在类中是否有构建,或者我应该自己编程?

对不起,不好解释。

我的代码。我现在明白,我得到命中为子,还包括其他的结果:)

protected void Button_search_Click(object sender, EventArgs e) 
    { 
     string searchTerm = TextBox1.Text.ToString().ToLower(); 

     TableRow row; 
     TableCell cell; 

     int rowNumber = 1; 

     foreach (Materiell mat in allItems) 
     { 
      if (searchTerm.Contains(mat.itemID.ToString().ToLower()) || 
       searchTerm.Contains(mat.manufacturer.ToLower()) || 
       searchTerm.Contains(mat.model.ToLower()) || 
       searchTerm.Contains(mat.serialNo.ToLower()) || 
       searchTerm.Contains(mat.dateProd.ToString().ToLower()) || 
       searchTerm.Contains(mat.location.ToLower()) || 
       searchTerm.Contains(mat.mainCategory.ToLower()) || 
       searchTerm.Contains(mat.subCategory.ToLower()) || 
       searchTerm.Contains(mat.dateAcquired.ToString().ToLower()) || 
       searchTerm.Contains(mat.price.ToString().ToLower()) || 
       searchTerm.Contains(mat.ownerID.ToString().ToLower()) || 
       searchTerm.Contains(mat.extra.ToString().ToLower()) || 
       searchTerm.Contains(mat.textComment.ToLower()) || 
       searchTerm.Contains(mat.active.ToString().ToLower())) 
      { 
       row = new TableRow(); 
       row.ID = "row" + rowNumber.ToString(); 
       rowNumber++; 

       cell = new TableCell(); 
       cell.Text = "<a href=\"#\" class=\"opendiv\">" + mat.itemID.ToString() + "</a>"; 
       row.Cells.Add(cell); 

       cell = new TableCell(); 
       cell.Text = mat.manufacturer.ToString(); 
       row.Cells.Add(cell); 

       cell = new TableCell(); 
       cell.Text = mat.model.ToString(); 
       row.Cells.Add(cell); 

       cell = new TableCell(); 
       cell.Text = mat.serialNo.ToString(); 
       row.Cells.Add(cell); 

       cell = new TableCell(); 
       cell.Text = mat.dateProd.ToString(); 
       row.Cells.Add(cell); 

       cell = new TableCell(); 
       cell.Text = mat.location.ToString(); 
       row.Cells.Add(cell); 

       cell = new TableCell(); 
       cell.Text = mat.mainCategory.ToString(); 
       row.Cells.Add(cell); 

       cell = new TableCell(); 
       cell.Text = mat.subCategory.ToString(); 
       row.Cells.Add(cell); 

       cell = new TableCell(); 
       cell.Text = mat.dateAcquired.ToString(); 
       row.Cells.Add(cell); 

       cell = new TableCell(); 
       cell.Text = mat.price.ToString(); 
       row.Cells.Add(cell); 

       cell = new TableCell(); 
       cell.Text = mat.ownerID.ToString(); 
       row.Cells.Add(cell); 

       cell = new TableCell(); 
       cell.Text = mat.extra.ToString(); 
       row.Cells.Add(cell); 

       cell = new TableCell(); 
       cell.Text = mat.ownDefData.ToString(); 
       row.Cells.Add(cell); 

       cell = new TableCell(); 
       cell.Text = mat.textComment.ToString(); 
       row.Cells.Add(cell); 

       cell = new TableCell(); 
       cell.Text = mat.active.ToString(); 
       row.Cells.Add(cell); 

       Table1.Rows.Add(row); 
      } 
     } 
    } 
+2

你可以张贴的代码片段,因为根据文档“雅图”应该打在“拖拉机”:http://msdn.microsoft.com/en-us/library/dy85x1sa(v=vs.100).aspx – LexyStardust 2012-03-29 10:06:24

+2

'“拖拉机”.Contains(“acto”)'应该返回'true'。您可能想要发布一些代码,以便我们可以看到迄今为止尝试的内容以及可能出错的位置。 – Rawling 2012-03-29 10:06:28

+0

Gah。没有一个答案能够解决这个问题。看看Lucene.NET,也许(你似乎在寻找全文搜索/索引;这可能是一个库类型的应用程序?) – sehe 2012-03-29 10:21:06

回答

11

"some string".Contains("str")将返回true,您是否遇到大小写敏感问题?

如果是这样,你可以这样做:

public static bool Contains(this string source, string toCheck, StringComparison comp) { 
    return source.IndexOf(toCheck, comp) >= 0; 
} 

string title = "STRING"; 
bool contains = title.Contains("string", StringComparison.OrdinalIgnoreCase); 

(来自Case insensitive 'Contains(string)'两者)​​

+1

整洁的小扩展方法。考虑一个被盗! – LexyStardust 2012-03-29 10:10:31

+0

正确...'IndexOf'方法有'Contains'方法缺少的'StringComparison'方法,没有想到这一点。这比在检查前使用'ToUpper'好。立即纳入我目前正在开展的项目。 :) – Guffa 2012-03-29 10:17:34

+0

OMG。令人惊讶的是,这被接受为答案。那么,如果你真的想全文搜索,请看这里:http://stackoverflow.com/questions/9923158/c-sharp-contains-part-of-string/9924084#9924084 – sehe 2012-03-29 11:01:28

3

使用IndexOf

string searchWithinThis = "ABCDEFGHIJKLMNOP"; 
string searchForThis = "DEF"; 
int firstCharacter = searchWithinThis.IndexOf(searchForThis); 

Console.WriteLine("First occurrence: {0}", firstCharacter); 

如果未找到字符串,则返回-1。它对于还知道在哪里发现字符串非常有用。

+0

其实他已经做到了。 'String.Contains'方法只是调用'IndexOf'。 – Guffa 2012-03-29 10:20:08

0

string.Contains方法并查找子字符串中的任何地方。

"asdf".Contains("as") --> True 
"asdf".Contains("sd") --> True 
"asdf".Contains("df") --> True 
"asdf".Contains("xy") --> False 

然而,比较区分sensetive,所以你可能需要转换情况下,如果你想的情况下insesetive搜索:

"Asdf".Contains("as") --> False 
"Asdf".Contains("As") --> True 

"Asdf".ToUpper().Contains("as".ToUpper()) --> True 
1
class SearchInString 
{ 
    static void Main() 
    { 
     string strn= "A great things are happen with great humans."; 
     System.Console.WriteLine("'{0}'",strn); 

     bool case1= strn.StartsWith("A great"); 
     System.Console.WriteLine("starts with 'A great'? {0}", case1); 

     bool case2= strn.StartsWith("A great", System.StringComparison.OrdinalIgnoreCase); 
     System.Console.WriteLine("starts with 'A great'? {0} (ignoring case)", case2); 

     bool case3= strn.EndsWith("."); 
     System.Console.WriteLine("ends with '.'? {0}", case3); 

     int start= strn.IndexOf("great"); 
     int end= strn.LastIndexOf("great"); 
     string strn2 = strn.Substring(start, end- start); 
     System.Console.WriteLine("between two 'great' words: '{0}'", strn2); 
    } 
} 
2

对于妈和笑声我认为这是一个不错的午休项目,想出一个简单但优雅的问题解决方案(据我所知:)):

例如

// I made up a Material class for testing: 
public class Materiel 
{ 
    public string A { get; set; } 
    public int B { get; set; } 
    public DateTime? C { get; set; } 
    public string D { get; set; } 
    public Nested E { get; set; } 
}  

// [...] usage: 

foreach (var pattern in new[]{ "World" , "dick", "Dick", "ick", "2012", "Attach" }) 
    Console.WriteLine("{0} records match '{1}'", Database.Search(pattern).Count(), pattern); 

输出:

2 records match 'World' 
1 records match 'dick' 
1 records match 'Dick' 
2 records match 'ick' 
1 records match '2012' 
2 records match 'Attach' 

该代码还支持

  • 正则表达式匹配
  • 任何属性类型(例如可空DateTime是否或嵌套类)
  • 显示属性匹配的模式/子

享受:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Reflection; 
using System.Text.RegularExpressions; 

namespace AClient 
{ 
    public class Materiel 
    { 
     public string A { get; set; } 
     public int B { get; set; } 
     public DateTime? C { get; set; } 
     public string D { get; set; } 
     public Nested E { get; set; } 
    } 

    public struct Nested 
    { 
     public string Data { get; set; } 
     public override string ToString() { return string.Format("Extra: {0}", Data); } 
    } 


    public static class FullText 
    { 
     public class PropMatched<T> { public PropertyInfo Property; public T Item; } 

     public static IEnumerable<PropMatched<T> > ByProperty<T>(this IEnumerable<T> items, string substr) 
     { 
      return items.ByProperty(new Regex(Regex.Escape(substr), RegexOptions.IgnoreCase)); 
     } 

     public static IEnumerable<PropMatched<T> > ByProperty<T>(this IEnumerable<T> items, Regex pattern) 
     { 
      return items.Select(i => i.MatchingProperties(pattern)).Where(m => null != m); 
     } 

     public static IEnumerable<T> Search<T>(this IEnumerable<T> items, string substr) 
     { 
      return items.Search(new Regex(Regex.Escape(substr), RegexOptions.IgnoreCase)); 
     } 

     public static IEnumerable<T> Search<T>(this IEnumerable<T> items, Regex pattern) 
     { 
      return items.Where(i => null != i.MatchingProperties(pattern)); 
     } 

     public static PropMatched<T> MatchingProperties<T>(this T item, Regex pattern) 
     { 
      if (null == pattern || null == item) return null; 

      var properties = item.GetType().GetProperties(BindingFlags.Public | BindingFlags.FlattenHierarchy | BindingFlags.Instance); 
      var matches = from prop in properties 
          let val = prop.GetGetMethod(true).Invoke(item, new object[]{}) 
          where pattern.IsMatch((val??"").ToString()) 
          select prop; 

      var found = matches.FirstOrDefault(); 
      return found == null ? null : new PropMatched<T> {Item = item, Property = found}; 
     } 
    } 

    class Client 
    { 
     private static readonly IEnumerable<Materiel> Database = new List<Materiel> 
      { 
       new Materiel { 
         A = "Hello", B = 1, C = null, D = "World", 
         E = new Nested {Data = "Attachment"} 
        }, 
       new Materiel { 
         A = "Transfigured", B = 2, C = null, D = "Nights", 
         E = new Nested {Data = "Schoenberg"} 
        }, 
       new Materiel { 
         A = "Moby", B = 3, C = null, D = "Dick", 
         E = new Nested {Data = "Biographic"} 
        }, 
       new Materiel { 
         A = "Prick", B = 4, C = DateTime.Today, D = "World", 
         E = new Nested {Data = "Attachment"} 
        }, 
       new Materiel { 
         A = "Oh Noes", B = 2, C = null, D = "Nights", 
         E = new Nested {Data = "Schoenberg"} 
        }, 
      }; 


     static void Main() 
     { 
      foreach (var pattern in new[]{ "World" , "dick", "Dick", "ick", "2012", "Attach" }) 
       Console.WriteLine("{0} records match '{1}'", Database.Search(pattern).Count(), pattern); 

      // regex sample: 
      var regex = new Regex(@"N\w+s", RegexOptions.IgnoreCase); 

      Console.WriteLine(@"{0} records match regular expression 'N\w+s'", Database.Search(regex).Count()); 

      // with context info: 
      foreach (var contextMatch in Database.ByProperty(regex)) 
      { 
       Console.WriteLine("1 match of regex in propery {0} with value '{1}'", 
        contextMatch.Property.Name, contextMatch.Property.GetGetMethod().Invoke(contextMatch.Item, new object[0])); 

      } 
     } 
    } 
} 
+0

看到它住在这里:** [ http://ideone.com/UWgQe](http://ideone.com/UWgQe)** – sehe 2012-03-29 11:05:04