Regex 101 Exercise I2 – Find two words in a string


I2 – Find two words in a string


Find any string that has the following two words in it: “dog” and “vet”


(yes, I know, I didn’t get last week’s discussion out there. It will be there shortly…)

Comments (10)

  1. Hasani says:

    (?m)(?<string>^.*?((bdogb.*?bvetb)|(bvetb.*?bdogb)).*?$)

  2. Anonymous says:

    permutation is not very scalable, right? what if you need find 3 or 10 words? can you do

    ^(?=.*dog)(?=.*vet)

    ?

    I would think using IndexOf is simpler and probably results in better performance, no?

  3. Ryan says:

    I didn’t know about the word boundry thing, cool. Here’s my modification:

    ^.*?((b(D|d)og(s?)b.*?b(V|v)et(s?)b)|(b(V|v)et(s?)b.*?b(D|d)og(s?)b)).*?$

    which correctly matches (or doesn’t match) the following:

    I took the dog to the vet.

    The vet liked the dog.

    There are a lot of dogs that go to vets everyday.

    Dog can start a sentence that ends with vet.

    Vet can start a sentence that ends with dog

    The war veteran ate a hotdog.

    This string has a dog but not a you know what.

    This string has a vet but not a you know what.

  4. Anonymous says:

    Come on, you guys are killing me with all these permutations and lower-case/upper-case, you could use RegexOptions.IgnoreCase or (?i)

  5. Ryan says:

    An ideal state machine would execute in little more then the time it takes to call IndexOf once for the substring that is furthest down the string you are searching regardless of how many strings it is searching for. I don’t know how much extra gets compiled into a RegEx in .NET though, plus you have to add in the time it takes to compile.

  6. Maurits says:

    Easy… use two regex’s.

    In Perl:

    if (/dog/i and /vet/i)

    {



    }

    In C#:

    if (

    Regex.IsMatch(s, "bdogb", RegexOptions.IgnoreCase)

    &&

    Regex.IsMatch(s, "bvetb", RegexOptions.IgnoreCase)

    )

    {



    }

    Permutations don’t scale, of course.

    b’s are optional.

    Even with b’s, _dog_ won’t match. This is probably a feature.

    A full-blown word search feature would probably build an index.

  7. Maurits says:

    If I /had/ to use a single expression it would be very similar to Anonymous’s first post:

    ^(?=.*dog)(?=.*vet)

    My only modifications would be:

    * minimalize the matches (for performance)

    * add comments (for readability)

    * reverse "dog" and "vet" (for performance… I assume "vet" occurs less frequently)

    * indent (for readability… underscores added because this blog strips leading spaces…)

    _ ^ # start of string

    _ (?= # is there, ahead…

    ___ .*? # anywhere in the string (start at the beginning)

    ___ bvetb # a "vet", perchance? (b’s optional)

    _ ) # well? Is there? Go check.

    # Assuming there is a "vet",

    _ (?= is there, ahead…

    ___ .?* # anywhere in the string (start at the beginning)

    ___ bdogb # a "dog", perchange? (b’s optional)

    _ )

    I’d line up the comments too… but this blog isn’t likely to let me do that, given that the font isn’t fixed-width…

Skip to main content