2011-02-02 3 views
13

У меня естьКак проверить, если любое слово в моем списке <string> содержится в тексте

List<string> words = new List<string> {"word1", "word2", "word3"}; 

И я хочу, чтобы проверить с помощью LINQ, если моя строка содержит любое из этих слов; Smthng как:

var q = myText.ContainsAny(words); 

И второе, если у меня есть список предложений тоже:

List<string> sentences = new List<string> { "sentence1 word1" , "sentence2 word2" , "sentence3 word3"}; 

, а также Неет, чтобы проверить, если любой из них предложения содержит любое из этих слов!

var q = sentences.Where(s=>words.Any(s.text)).... 
+0

Нужно ли содержать целые слова или подстроки? –

ответ

35

Вы можете использовать простой запрос LINQ, если все, что вам нужно, чтобы проверить наличие подстроки:

var q = words.Any(w => myText.Contains(w)); 
// returns true if myText == "This password1 is weak"; 

Если вы хотите проверить целые слова, вы можете использовать регулярное выражение:

  1. Matching с регулярным выражением, которое является дизъюнкцией всех слов:

    // you may need to call ToArray if you're not on .NET 4 
    var escapedWords = words.Select(w => @"\b" + Regex.Escape(w) + @"\b"); 
    // the following line builds a regex similar to: (word1)|(word2)|(word3) 
    var pattern = new Regex("(" + string.Join(")|(", escapedWords) + ")"); 
    var q = pattern.IsMatch(myText); 
    
  2. Нарезка строка в слова с регулярным выражением, и тестирование на членство в слове коллекции (это получит быстрее, если вы используете, чтобы слова в HashSet вместо List):

    var pattern = new Regex(@"\W"); 
    var q = pattern.Split(myText).Any(w => words.Contains(w)); 
    

Для того чтобы отфильтровать коллекцию предложений по этому критерию все, что вы должны сделать его положить его в функцию и вызвать Where:

// Given: 
// bool HasThoseWords(string sentence) { blah } 
var q = sentences.Where(HasThoseWords); 

Или положить его в лямбда:

var q = sentences.Where(s => Regex.Split(myText, @"\W").Any(w => words.Contains(w))); 
+0

Я бы пошел с linq. Вы не избегаете управляющих символов в регулярном выражении. –

+0

Поиск выделенной строки отличается от трех дискретных запросов, поскольку границы начала и конца слова сливаются и могут приводить к ложному совпадению. – Xhalent

+0

thnx для вашего ответа, но можете ли вы посоветовать мне в случае, если контейнер слов является данным? – user690069

5
var q = words.Any(w => myText.Contains(w)); 

Чтобы вернуть все предложения, которые содержат 1 или более слов:

var t = sentences.Where(s => words.Any(w => s.Contains(w))); 

      foreach (var sentence in t) 
      { 
       Console.WriteLine(sentence); 
      } 
+0

Содержит, а не равен. –

1

Для ваше первое условие

List<string> words = new List<string> { "word1", "word2", "word3" }; 
string test = "word1"; 
bool isFound = words.Contains(test); 

Для вашего второго условия

bool isFound = sentences.Any(x => x.Split(new char[] { ' ' }).Contains(test)); 

Как неродственная боковая нота

Вы меняющаяся сферу на вопрос после того, как получить некоторые ответы, и что это не является хорошим способом, чтобы задавать вопросы. :)

+0

'words.Contains (« Эта строка имеет слово1 »)' будет false, но должна быть true («[...], если моя строка содержит ЛЮБЫЕ из этих слов».) –

2

Хотя большинство представленных решений являются функциональными (все вызовы Contains, которые предоставят вам желаемое решение), если список и текст являются большими, могут возникнуть проблемы с производительностью.

Из-за проблемы, о которой было сказано, я думаю, что вы называете слово чем-либо между пробелами или любым другим делителем.Итак, я бы порекомендовал вам разделить ваш myText на список слов и сравнить каждый из них со списком слов, теперь с помощью содержит.

Это, конечно, более сложный путь; Вы должны были бы правильно разделить слова - но с большими строками (например, текстовым файлом) может быть некоторое увеличение производительности.

Смежные вопросы