2

I'm looking for a JS regex to match full words, but not to match at all if there is any different word (any failure).

Eg: Match for \b(dog|cat)\b


cat dog cat --> everything is matched. OK.

dog --> dog is matched even if cat does not exist here. OK.

dog cata --> dog is matched, cata not. I don't want any match at all.

Hedam
  • 2,209
  • 27
  • 53
de-facto
  • 283
  • 2
  • 8
  • See https://stackoverflow.com/a/1177841/3832970. Just remove `(?i)`. – Wiktor Stribiżew Sep 18 '18 at 12:43
  • Yes, but this does not match on "test" alone. Added more details to post. – de-facto Sep 18 '18 at 12:50
  • See [`^(?=.*\bdog\b)(?=.*\bcat\b)`](https://regex101.com/r/WVNXgp/1) and it is still a dupe of [this answer in the linked thread](https://stackoverflow.com/a/24698179/3832970) – Wiktor Stribiżew Sep 18 '18 at 12:53
  • What about `dog fish`? – Toto Sep 18 '18 at 12:56
  • Is that [^(?:(?=.*\bdog\b)(?=.*\bcat\b).*|cat|dog)$](https://regex101.com/r/YCgsnj/1) what you want? – Toto Sep 18 '18 at 13:16
  • @Toto: Thank you so much. Looks perfect. – de-facto Sep 18 '18 at 13:29
  • Regex is not the only tool at your disposal. It's very straightforward to split the words apart and just test that they are all within your allowed set of words: `"dog cat dog".split(" ").every(word => word == 'dog' || word == 'cat'); // true` – user229044 Sep 18 '18 at 16:33
  • In fact that's true. I'm sorry for having asked this question regarding regex as my first approach was with regex, but you are completely right. – de-facto Sep 19 '18 at 06:11

2 Answers2

0

Is that ^(?:(?=.*\bdog\b)(?=.*\bcat\b).*|cat|dog)$ what you want?

Explanation:

^                       : beginning of the string
  (?:                   : start non capture group
      (?=.*\bdog\b)     : positive lookahead, zero-length assertion, make sure we have dog somewhere in the string
      (?=.*\bcat\b)     : positive lookahead, zero-length assertion, make sure we have cat somewhere in the string
      .*                : 0 or more any character
    |                   : OR
      cat               : cat alone
    |                   : OR
      dog               : dog alone
  )                     : end group
$                       : end of string

var test = [
    'dog cat',
    'cat dog',
    'dog',
    'cat',
    'dog cata',
    'cat fish',
];
console.log(test.map(function (a) {
  return a + ' ==> ' + a.match(/^(?:(?=.*\bdog\b)(?=.*\bcat\b).*|cat|dog)$/);
}));
Toto
  • 89,455
  • 62
  • 89
  • 125
0

So, basically you want to check all of your words in your string matches the regexor all of your string should be from a list of string, isn't it? Let's split all the words and check whether all of them belongs from your list of strings.

var reg = /dog|cat|rat/,
    input1 =  "dog   cat      rat",
    input2 = "dog cata   rat",
    input3 = "abcd efgh",
    isMatched = s => !(s.match(/\S+/g) || []).some(e => !(new RegExp(e).test(reg)));
    
console.log(isMatched(input1));
console.log(isMatched(input2));
console.log(isMatched(input3));
Koushik Chatterjee
  • 4,106
  • 3
  • 18
  • 32