Regex: I Want This and That and That... in Any Order

Regex: I want this AND that AND that... in any order

You can use (?=…) positive lookahead; it asserts that a given pattern can be matched. You'd anchor at the beginning of the string, and one by one, in any order, look for a match of each of your patterns.

It'll look something like this:

^(?=.*one)(?=.*two)(?=.*three).*$

This will match a string that contains "one", "two", "three", in any order (as seen on rubular.com).

Depending on the context, you may want to anchor on \A and \Z, and use single-line mode so the dot matches everything.

This is not the most efficient solution to the problem. The best solution would be to parse out the words in your input and putting it into an efficient set representation, etc.

Related questions

  • How does the regular expression (?<=#)[^#]+(?=#) work?

More practical example: password validation

Let's say that we want our password to:

  • Contain between 8 and 15 characters
  • Must contain an uppercase letter
  • Must contain a lowercase letter
  • Must contain a digit
  • Must contain one of special symbols

Then we can write a regex like this:

^(?=.{8,15}$)(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[!@#$%^&*]).*$
\__________/\_________/\_________/\_________/\______________/
length upper lower digit symbol

Regex: Specified words in any order

For Regex 1:

var re = /^(?=.*?\baaa\b)(?=.*?\bbbb\b)(?=.*?\bccc\b)\b(?:aaa|bbb|ccc)\b(?: +\b(?:aaa|bbb|ccc)\b)*$/;var res = document.getElementById('result');res.innerText += re.test('aaa ccc bbb');res.innerText += ', ' + re.test('aaa ccc ddd');res.innerText += ', ' + re.test('aaa ddd bbb');res.innerText += ', ' + re.test('ccc bbb ccc');
<div id="result"></div>

Regular expression to match words in any order but words can be optional

You need to anchor your regex to the beginning of a line (^) and make each of the positive lookaheads that contain named capture groups optional.

Also, you have some numbered capture groups that could be non-capture groups, which would be less confusing since you are only interested in the named capture groups. Lastly, you a missing some word boundaries.

I suggest you change your expression to the following.

^(?=.*(?P<gender>\b(?:fe)?male\b))?(?=.*(?P<quality>\b(?:green|amber|red)\b))?(?=.*(?P<feedback>\b(?:positive|negative)\b))?.*

Demo

The regular expression can be broken down as follows.

^                         # match beginning of line
(?= # begin positive lookahead
.* # match zero or more characters
(?P<gender> # begin named capture group 'gender'
\b # match a word boundary
(?:female|male) # one of the two words
\b # match a word boundary
) # end capture group 'gender'
)? # end positive lookahead and make it optional
(?=                       # begin positive lookahead
.* # match zero or more characters
(?P<quality> # begin named capture group 'quality'
\b # match a word boundary
(?:green|amber|red) # match one of the three words
\b # match a word boundary
) # end named capture group 'quality'
)? # end positive lookahead and make it optional
(?=                       # begin positive lookahead
.* # match zero or more characters
(?P<feedback> # begin named capture group 'feedback'
\b # match a word boundary
(?:positive|negative) # match one of the two words
\b # match a word boundary
) # end named capture group 'feedback'
)? # end positive lookahead and make it
.* # match zero or more characters (the line)

Regex to match any string that keeps the order in a sequence even if it's not complete

I think ? after each character does what you want:

regex(str, 'a?b?c?d?. . . ')

(The . . . isn't part of the string. It is just notation to indication that you continue following the same patter of character/question mark.)

Find all matches in string with regex in any order with Javascript

No need for the regex, just loop through the words using every() , and check each keyword using includes() (See below);

console.log(Check("How to edit an image", ["image","edit","not"])); // false
console.log(Check("How to edit an image", ["image","edit"])); // true

function Check(title, keywords) {
return keywords.every(word => title.indexOf(word) > -1);
}

Making a regex that can find two words where the order can be reversed

I would use the following pattern:

private\s*?(((final\s*?static)|(static\s*?final))|(final)|(static))?\s*?int\s*?goodyear\(.*?\){

The pattern includes ((final\s*?static)|(static\s*?final)) which allows you to match "final static" or "static final".

https://regex101.com/r/YVd4hU/1

Extract(subset) two ords same time in any order with stringr in R

Using str_subset - regex would be to specify text-1 followed by characters (.*) and then text-2 or (|) in the reverse way

library(stringr)
str_subset(texts, 'text-1.*text-2|text-2.*text-1')
[1] "I-have-text-1-and-text-2" "I-have-text-2-and-text-1"

Javascript regex to match a list of specific words in any order

If you only want to match the colours in that particular sentence, you can avoid the issue of only getting the last match of the capture group by using lookarounds instead, for example:

const text = 'On the green and green and green and purple and purple and yellow grass';
const colors = '(?:green|purple|yellow|red)';

const regex = new RegExp(
`(?<=On the (?:${colors} and )*)${colors}(?=(?: and ${colors})* grass)`,
'g');

console.log(text.match(regex));

Regex with repeating group in any order

The category prefix has a different pattern, ending with a forward slash (c/), so you should add an option for that.

I would suggest this regular expression:

(\bc\/|\bf-brand-|\bf-hair-porosity-|\bf-shampoo-type-)((?:(?!\/f-).)*)

This will capture two groups:

* the prefix
* the value

It will allow / to occur inside a single match when it is not followed by ´f-´. This is where a subcategory could be included in the category match.

regex pattern to find words in any order

What about a list of "allowed words" only including a space and comma?

^(?:combine|online|store| |,)+$

Test here



Related Topics



Leave a reply



Submit