Coder-M
Coder-M

Reputation: 43

Regular expression that matches all specified characters in any order at the start of the line

I'm looking for a regexp that matches any line that contains 'B', 'R', 'A' and 'S' (in any order) at the start. It would match all the following lines, except the last two.

BRASIL
BSRAIL
BARSILERO
BRASILERA
BRASILEÑA
BRASILEÑO
BARBADOS
BOSNIA AND HERZEGOVINA

I tried the following:

^(B|R|A|S){4}.*$
^(?=.*B)(?=.*R)(?=.*A)(?=.*S).*$
^(?=.{4})(?=.*B)(?=.*R)(?=.*A)(?=.*S).*$
^(?=.*B)(?=.*R)(?=.*A)(?=.*S){4}.*$
^(?=.*B){1}(?=.*R){1}(?=.*A){1}(?=.*S){1}.*$

Upvotes: 4

Views: 202

Answers (3)

bobble bubble
bobble bubble

Reputation: 18490

How about using some lookaheads and limits:

^(?=.{0,3}B)(?=.{0,3}R)(?=.{0,3}A).{0,3}S

See this demo at regex101 (for full match output see another demo)

Upvotes: 0

knittl
knittl

Reputation: 265201

There are only 24 permutations :)

^(ABRS|BARS|RABS|ARBS|BRAS|RBAS|RBSA|BRSA|SRBA|RSBA|BSRA|SBRA|SARB|ASRB|RSAB|SRAB|ARSB|RASB|BASR|ABSR|SBAR|BSAR|ASBR|SABR)

You can shorten it a bit by grouping pairs of two:

^((AB|BA)(RS|SR)|(AR|RA)(BS|SB)|(AS|SA)(BR|RB)|(BR|RB)(AS|SA)|(BS|SB)(AR|RA)|(RS|SR)(AB|BA))

Each double pair matches 4 inputs, e.g., (AB|BA)(RS|SR) can match:

ABRS
ABSR
BARS
BASR

Upvotes: 3

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626747

You can use

^([BRAS])(?!\1)([BRAS])(?!\1|\2)([BRAS])(?!\1|\2|\3)([BRAS])

See the regex demo. Details:

  • ^ - start of string
  • ([BRAS]) - Group 1: B, R, A or S
  • (?!\1)([BRAS]) - Group 2: B, R, A or S but not as in Group 1
  • (?!\1|\2)([BRAS]) - Group 3: B, R, A or S but not as in Group 1 and 2
  • (?!\1|\2|\3)([BRAS]) - Group 4: B, R, A or S but not as in Group 1, 2 and 3.

Note that when using the pattern with MySQL v.8, you need to double the backslashes:

"^([BRAS])(?!\\1)([BRAS])(?!\\1|\\2)([BRAS])(?!\\1|\\2|\\3)([BRAS])"

Upvotes: 5

Related Questions