30

I'm looking to know when a string does not contain two strings. For example.

string firstString = "pineapple"
string secondString = "mango"

string compareString = "The wheels on the bus go round and round"

So, I want to know when the first string and second string are not in the compareString.

How?

ΩmegaMan
  • 29,542
  • 12
  • 100
  • 122

7 Answers7

101

This should do the trick for you.

For one word:

if (!string.Contains("One"))

For two words:

if (!(string.Contains("One") && string.Contains("Two")))
Xm7X
  • 861
  • 1
  • 11
  • 23
Woot4Moo
  • 23,987
  • 16
  • 94
  • 151
  • 1
    You are only checking one string, while he asked for both! – Younes May 30 '11 at 14:15
  • 7
    is it not trivial to extract the information out from that statement? – Woot4Moo May 30 '11 at 14:18
  • 3
    this seems like the best answer +1 – Blake Feb 14 '14 at 16:46
  • How would you use this in a controller w/ the following setup? `IQueryable data = from table1 in db.myTable1 join table2 in db.myTable2 on table1.myID equals myTable2.myID where table1.(!someColumn.Contains("thisText"))` The above fails on the last line bc incorrect C# syntax in that case. How could I do this 'does not contain' check here? – Kyle Vassella May 28 '20 at 20:46
12

You should put all your words into some kind of Collection or List and then call it like this:

var searchFor = new List<string>();
searchFor.Add("pineapple");
searchFor.Add("mango");

bool containsAnySearchString = searchFor.Any(word => compareString.Contains(word));

If you need to make a case or culture independent search you should call it like this:

bool containsAnySearchString = 
   searchFor.Any(word => compareString.IndexOf
     (word, StringComparison.InvariantCultureIgnoreCase >= 0);
Akram Shahda
  • 14,655
  • 4
  • 45
  • 65
Oliver
  • 43,366
  • 8
  • 94
  • 151
  • This is overkill. The answer mentioning 'utilize short-circuiting' is correct and simple. – Scott Shaw-Smith Oct 11 '13 at 17:21
  • 1
    @ScottShaw-Smith: If you have only two words maybe. If you are going to search for more words or like to switch the words, this approach maks more sense. – Oliver Oct 14 '13 at 06:07
9

So you can utilize short-circuiting:

bool containsBoth = compareString.Contains(firstString) && 
                    compareString.Contains(secondString);
jason
  • 236,483
  • 35
  • 423
  • 525
5

Use Enumerable.Contains function:

var result =
    !(compareString.Contains(firstString) || compareString.Contains(secondString));
Akram Shahda
  • 14,655
  • 4
  • 45
  • 65
  • i believe that is incorrect. first condition is false, and second condition is true. false + true = true – Woot4Moo May 30 '11 at 14:21
  • 1
    @Woot: There's a global negation at the front. This will only be true if neither word is in the string, which is what the OP asked. – Joe May 30 '11 at 14:24
  • @Joe with the global not it will be true in every evaluation except the one where both are present. In Or tables the only condition that evals to true is ` T + T` which would be indicative of when both strings are present. – Woot4Moo May 30 '11 at 15:08
  • I have to pull down the requirements, but gladly – Woot4Moo May 30 '11 at 15:23
  • Also it does fail in java,not that the question asked about java just saying. – Woot4Moo May 30 '11 at 15:24
  • @Woot4Moo: It has been tested, and I am satisfied with the result :) I was wondering, do you know how to read french? Not that I've wrote my comment in french, It has just came to my mind :D – Akram Shahda May 30 '11 at 15:55
  • very little french, a bit more spanish. – Woot4Moo May 30 '11 at 17:50
  • @Woot: you misread the requirement. He said "first string and second string are not in the compareString." The only thing that evaluates to T is F + F. – Joe May 30 '11 at 19:34
  • @Woot4Moo: I guess you need to focus on some of those languages and forget about the others because it seems that you have started mixing a little between french and Java... In my opinion, keep focusing on Java. That is better for you. – Akram Shahda May 30 '11 at 19:40
4
bool isFirst = compareString.Contains(firstString);
bool isSecond = compareString.Contains(secondString );
Stecya
  • 22,896
  • 10
  • 72
  • 102
4

Option with a regexp if you want to discriminate between Mango and Mangosteen.

var reg = new Regex(@"\b(pineapple|mango)\b", 
                       RegexOptions.IgnoreCase | RegexOptions.Multiline);
   if (!reg.Match(compareString).Success)
      ...
Akram Shahda
  • 14,655
  • 4
  • 45
  • 65
Alex K.
  • 171,639
  • 30
  • 264
  • 288
  • http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags if I misread what the OP typed I'll give you the points back :) – Woot4Moo May 30 '11 at 15:30
  • 1
    The question relates to an arbitrary string search, the op does not specify html parsing so the assumption is markup is not an issue (the same assumption that every answer makes) – Alex K. May 30 '11 at 15:54
  • This is the correct answer, with a bad example. (I provide an separate answer with a better explanation below). There are two issues with this, 1) `RegexOptions.Multiline` only affect patterns that have `^` and `$` in them; to allow those anchors to be spread across many lines. Your pattern does not use them and that can be removed. 2) use of `IsMatch` would clean up the example code. – ΩmegaMan Dec 14 '21 at 17:08
1

The accepted answer, and most others will present a logic failure when an unassociated word contains another. Such as "low" in "follow". Those are separate words and .Contains and IndexOf will fail on those.

Word Boundary

What is needed is to say that a word must stand alone and not be within another word. The only way to handle that situation is using regular expressions and provide a word boundary \b rule to isolate each word properly.

Tests And Example

string first = "name";
var second = "low";

var sentance = "Follow your surname";
  
var ignorableWords = new List<string> { first, second };

The following are two tests culled from other answers (to show the failure) and then the suggested answer.

// To work, there must be *NO* words that match.
ignorableWords.Any(word => sentance.Contains(word));   // Returns True (wrong)

ignorableWords.Any(word =>                            // Returns True (wrong)
                      sentance.IndexOf(word,
                               StringComparison.InvariantCultureIgnoreCase) >= 0);

// Only one that returns False

ignorableWords.Any(word => 
            Regex.IsMatch(sentance, @$"\b{word}\b", RegexOptions.IgnoreCase));

Summary

.Any(word =>Regex.IsMatch(sentance, @$"\b{word}\b", RegexOptions.IgnoreCase)

  • One to many words to check against.
  • No internal word failures
  • Case is ignored.
ΩmegaMan
  • 29,542
  • 12
  • 100
  • 122