var str = "This is a test. Here is word1 and here is word2, which may or may not exist.";
var matches = str.match( /word1|word2/g );
//-> ["word1", "word2"]

String.prototype.match will run a regex against the string and find all matching hits. In this case we use alternation to allow the regex to match either word1 or word2.

You need to apply the global flag to the regex so that match() will find all results.

If you care about matching only on word boundaries, use /\b(?:word1|word2)\b/g.

Answer from Phrogz on Stack Overflow
๐ŸŒ
O'Reilly
oreilly.com โ€บ library โ€บ view โ€บ regular-expressions-cookbook โ€บ 9781449327453 โ€บ ch05s02.html
5.2. Find Any of Multiple Words - Regular Expressions Cookbook, 2nd Edition [Book]
August 27, 2012 - The simple solution is to alternate between the words you want to match: ... More complex examples of matching similar words are shown in Recipe 5.3. var subject = "One times two plus one equals three."; // Solution 1: var regex = ...
Authors ย  Jan GoyvaertsSteven Levithan
Published ย  2012
Pages ย  609
Discussions

regex javascript - match multiple search terms ignoring their order - Stack Overflow
I would like to find all the matches of given strings (divided by spaces) in a string. (The way for example, iTunes search box works). That, for example, both "ab de" and "de ab" will return true ... More on stackoverflow.com
๐ŸŒ stackoverflow.com
Match multiple strings
I find peace in long walks. More on reddit.com
๐ŸŒ r/regex
5
2
August 21, 2022
javascript - Regular Expression to MATCH ALL words in a query, in any order - Stack Overflow
I'm trying to build a search feature for a project which narrows down items based on a user search input and if it matches the keywords listed against items. For this, I'm saving the item keywords ... More on stackoverflow.com
๐ŸŒ stackoverflow.com
Multiple words in any order using regex - Stack Overflow
Do you know what words you want ... to match words that fit a particular pattern? Do you want to find out what position they're at? ... I know the exact words , dont car about multiples , dont need the position. I do need to be case insensitive ... Which regex flavor are you using? JavaScript, .NET, ... More on stackoverflow.com
๐ŸŒ stackoverflow.com
๐ŸŒ
Mozilla
developer.mozilla.org โ€บ en-US โ€บ docs โ€บ Web โ€บ JavaScript โ€บ Guide โ€บ Regular_expressions
Regular expressions - JavaScript - MDN Web Docs
2 weeks ago - Assertions include boundaries, which indicate the beginnings and endings of lines and words, and other patterns indicating in some way that a match is possible (including look-ahead, look-behind, and conditional expressions). ... Distinguish different types of characters. For example, distinguishing between letters and digits. ... Groups group multiple patterns as a whole, and capturing groups provide extra submatch information when using a regular expression pattern to match against a string.
๐ŸŒ
Regex Tester
regextester.com โ€บ 106416
search multiple words - Regex Tester/Debugger
Url checker with or without http:// ... format (yyyy-mm-dd) Url Validation Regex | Regular Expression - Taha Match an email address Validate an ip address nginx test Extract String Between Two STRINGS special characters check match whole word Match anything enclosed by square ...
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ how-to-match-multiple-parts-of-a-string-using-regexp-in-javascript
JavaScript โ€“ How to Match Multiple Parts of a String Using RegExp? | GeeksforGeeks
December 6, 2024 - The multiline property of a JavaScript regular expression indicates whether the m (multiline) flag is enabled. When enabled, the ^ and $ anchors match the start and end of each line within a string, rather than the entire string.JavaScript// ...
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ javascript โ€บ how-to-match-multiple-parts-of-a-string-using-regexp-in-javascript
JavaScript - How to Match Multiple Parts of a String Using RegExp? - GeeksforGeeks
July 23, 2025 - The exec() method allows you to find multiple matches one at a time. It returns an array for each match, and with the global flag, it can be used in a loop to find all matches. ... let s = "apple123 orange456 apple789"; let regex = /(\w+)(\d+)/g; ...
๐ŸŒ
Quora
quora.com โ€บ How-can-I-search-for-a-multiple-word-string-in-regex
How to search for a multiple-word string in regex - Quora
Quote/escape the phrase if it contains regex metacharacters. Decide whether to enforce word boundaries (\b). Choose whitespace handling: literal space, \s+, \s, or [\s\S] for cross-line. Add flags for case-insensitivity or dotall as needed. For presence without order, use lookahead assertions. Adopt the pattern that matches your exact requirement (exact phrase, flexible separators, cross-line, or order-independent).
Find elsewhere
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ javascript โ€บ how-to-search-for-multiple-words-within-a-string-or-array-in-javascript
How to Search for Multiple Words Within a String or Array in JavaScript? - GeeksforGeeks
November 14, 2024 - const array = ["Apple", "Banana", "Cherry", "Date", "Elderberry"]; const wordsToSearch = ["banana", "date", "fig"]; const regex = new RegExp(wordsToSearch.join("|"), "i"); const foundItems = array.filter(item => regex.test(item)); console.log("Matching words (case-insensitive):", foundItems); // Output: ["Banana", "Date"] ... If you have a complex scenario where you need to search for multiple words in both a string and an array, you can combine these approaches:
๐ŸŒ
TutorialsPoint
tutorialspoint.com โ€บ match-multiple-occurrences-in-a-string-with-javascript
Match multiple occurrences in a string with JavaScript?
To match multiple occurrences in a string, use regular expressions. Following is the code โˆ’ ยท function checkMultipleOccurrences(sentence) { var matchExpression = /(JavaScript?[^\s]+)|(typescript?[^\s]+)/g; return sentence.match(matchExpression); } var sentence="This is my first JavaScript ...
Top answer
1 of 4
69

You can achieve this will lookahead assertions

^(?=.*\bmeat\b)(?=.*\bpasta\b)(?=.*\bdinner\b).+

See it here on Regexr

(?=.*\bmeat\b) is a positive lookahead assertion, that ensures that \bmeat\b is somewhere in the string. Same for the other keywords and the .+ is then actually matching the whole string, but only if the assertions are true.

But it will match also on "dinner meat Foobar pasta"

2 of 4
10

stema's answer is technically correct, but it doesn't take performance into account at all. Look aheads are extremely slow (in the context of regular expressions, which are lightning fast). Even with the current logic, the regular expression is not optimal.

So here are some measurements, calculated on larger strings which contain all three words, running the search 1000 times and using four different approaches:

stema's regular expression

/^(?=.*\bmeat\b)(?=.*\bpasta\b)(?=.*\bdinner\b).+/

result: 605ms

optimized regular expression

/^(?=.*?\bmeat\b)(?=.*?\bpasta\b)(?=.*?\bdinner\b)/

uses lazy matching and doesn't need the end all selector

result: 291ms

permutation regular expression

/(\bmeat\b.*?(\bpasta\b.*?\bdinner\b|\bdinner\b.*?\bpasta\b)|\bpasta\b.*?(\bmeat\b.*?\bdinner\b|\bdinner\b.*?\bmeat\b)|\bdinner\b.*?(\bpasta\b.*?\bmeat\b|\bmeat\b.*?\bpasta\b))/

result: 56ms

this is fast because the first pattern is matching, if the last pattern matched, it would be even slower than the look ahead one (300 ms)

array of regular expressions

var regs=[/\bmeat\b/,/\bpasta\b/,/\bdinner\b/];
var result = regs.every(reg=>reg.test(text));

result: 26ms

Note that if the strings are crafted to not match, then the results are:

  • 521ms
  • 220ms
  • 161ms - much slower because it has to go through all the branches
  • 14ms

As you can see, in all cases just using a loop is an order of magnitude faster, not to mention easier to read.

The original question was asking for a regular expression, so my answer to that is the permutation regular expression, but I would not use it, as its size would grow exponentially with the number of search words.

Also, in most cases this performance issue is academic, but it is necessary to be highlighted.

๐ŸŒ
SitePoint
sitepoint.com โ€บ javascript
Searching for multiple words within a string or Array - JavaScript - SitePoint Forums | Web Development & Design Community
November 6, 2010 - <script type="text/javascript"> function wordsInStringArray( arr, str ) /* search array of strings 'arr' for any word in string 'str' */ { var wordGroup = str.replace( /^\\s+|\\s+$/g, "" ).split( /\\W+/ ), found = null, re; for( var i = 0; i < arr.length && !found; i++ ) for( var j = 0, wLen = wordGroup.length; j < wLen && !found; j++ ) if( ( re = new RegExp( "\\\\b" + wordGroup[ j ] + "\\\\b", "i" ) ).test( arr[ i ] ) ) found = { word : arr[ i ].match( re ), elem : arr[ i ] }; return found; } var stringArray = [ "jumped over", "the lazy dog", "the swift cat" ], wordString = " a cat, a dog, a rabbit and a hamster", result; if( ( result = wordsInStringArray( stringArray, wordString ) ) ) alert( '"' + result.word + '"' + '\ \ found in\ \ "' + result.elem + '"'); </script> stix_fs November 7, 2010, 1:24pm ยท
๐ŸŒ
regex101
regex101.com โ€บ library โ€บ fA2RAC
regex101: Matching multiple words in any order in the same string
Search among 15,000 community submitted regex patterns... ... Matching multiple words any order.
Top answer
1 of 4
9

You forgot to allow for a space between your "words":

\b\D*?\b(?:\s+\b\D*?\b)+
           ^^^

There are a number of other problems I can see:

I'm also rather suspicious of your definition of "word". Any non-numeric character also includes punctuation and whitespace. That's probably not what you really mean. You might want to try defining word like this instead: [^\d\s]+. This still allows words to contain punctuation, but it disallows both numerals and whitespace.

There is a problem with your usage of word boundaries - if a word can consist of punctuation then words beginning or ending on punctuation won't have a word boundary so your regular expression will miss them.

Are you searching for a string that contains at least two "words", and possibly also some numbers? Or must the string consist only of "words" and no numbers at all anywhere in the string? Currently your regular expression is looking for two consecutive "words" but in general they might not be consecutive.

2 of 4
3

You can globally search for a "word" and check the length of the .match() if a match is found:.

If two or more words are found, you're good:

var matches = string.match(/\b[^\d\s]+\b/g);
if ( matches && matches.length >= 2 ) 
    { /* Two or more words ... */ }; 

You can define a word as \b[^d\s]+\b, which is a word boundary \b, one or more non digits and non whitespaces [^d\s]+, and another word boundary \b. You have to make sure to use the global option g for the regex to find all the possible matches.

You can tweak the definition of a word in your regex. The trick is to make use of the length property of the .match(), but you should not check this property if there are no matches, since it'll break the script, so you must do if (matches && matches.length ...).

Additionally it's quite simple to modify the above code for X words where X is either a number or a variable.

jsFiddle example with your 4 examples

Top answer
1 of 2
1

For the situation you're describing, you don't even need regular expressions. If you split the search string on spaces; you can check every one of the words to match is contained within the array of search words.

function matchesAllWords(searchWords, inputString) {
  var wordsToMatch = inputString.toLowerCase().split(' ');

  return wordsToMatch.every(
    word => searchWords.indexOf(word) >= 0);
}

In the snippet below, typing in the input causes a recalculation of the searchWords. The matching li elements are then given the .match class to highlight them.

function updateClasses(e) {
  var searchWords = e.target.value.toLowerCase().split(' ');

  listItems.forEach(listItem => listItem.classList.remove('match'));

  listItems.filter(
      listItem =>
      matchesAllWords(searchWords, listItem.innerText))
    .forEach(
      matchingListItem =>
      matchingListItem.classList.add('match'));
}

function matchesAllWords(searchWords, inputString) {
  var wordsToMatch = inputString.toLowerCase().split(' ');
  
  return wordsToMatch.every(
    word => searchWords.indexOf(word) >= 0);
}

function searchProperties(e) {
  var searchWords = e.target.value.toLowerCase().split(' ');

  for (var property in propertiesToSearch) {
    if (matchesAllWords(searchWords, property)) {
      console.log(property, propertiesToSearch[property]);
    }
  }
}

var propertiesToSearch = {
  "red apples": 1,
  "juicy fruit": 2
};

listItems = [].slice.call(
  document.getElementById('matches').querySelectorAll('li')
);

document.getElementById('search').addEventListener('keyup', updateClasses);
document.getElementById('search').addEventListener('keyup', searchProperties);
.match {
  color: green;
}
<label for="search">
  Search:
</label>
<input type="text" name="search" id="search" />

<ul id="matches">
  <li>red apples</li>
  <li>juicy fruits</li>
</ul>

Update To use this kind of implementation to search for a property, use a for .. in loop like below. Again, see the snippet for this working in context.

function searchProperties(e) {
  var searchWords = e.target.value.toLowerCase().split(' ');

  for (var property in propertiesToSearch) {
    if (matchesAllWords(searchWords, property)) {
      console.log(property, propertiesToSearch[property]);
    }
  }
}

var propertiesToSearch = {
  "red apples": 1,
  "juicy fruit": 2
};
2 of 2
0

I think you might benefit from transforming your data structure from an object literal to an array like so:

const wordGroupings = [
  'red apples',
  'juicy fruits'
];

I wrote a processString function that accepts a string and some word-groupings as inputs and returns a filtered list of the word-groupings from where each word in the word-grouping occurs in the input string.

In other words let's imagine the test string is:

const testString = 'I like big, frozen whales.';

And let's further imagine that your wordGroupings array looked something like this:

const wordGroupings = [
  'whales frozen',
  'big frozen whales toucan',
  'big frozen',
  'sweaty dance club',
  'frozen whales big'
]

The output of calling processString(wordGroupings, testString) would be:

[
  'whales frozen',
  'big frozen',
  'frozen whales big'
]

If this is what you're looking for, here is the implementation of processString(..):

function processString(wordGroupings, testString) {
  var regexes = wordGroupings.map(words => ({
      origString: words,
      regex: new RegExp(words.replace(/\s+/g, '|'), 'g'),
      expCount: words.split(/\s+/g).length
    })
  );

  filtered = regexes.filter(({regex, expCount}) =>
    (testString.match(regex) || []).length === expCount
  );

  return filtered.map(dataObj => dataObj.origString);
}

Hope this helps!

๐ŸŒ
Regex Tester
regextester.com โ€บ 102251
Multiple Strings - Regex Tester/Debugger
Url checker with or without http:// ... format (yyyy-mm-dd) Url Validation Regex | Regular Expression - Taha Match an email address Validate an ip address nginx test Extract String Between Two STRINGS special characters check match whole word Match anything enclosed by square ...