I have the following regex: /\.([s]?[ac]ss)$/
. The problem is, it matches .scss
, .sass
, .css
, .ass
. How would I make it not match .ass
?

- 93
- 6
6 Answers
Also this will match .scss
, .sass
and .css
only, it is very readable and self-explanatory
/\.(sc|sa|c)ss$/

- 120,726
- 26
- 164
- 177
-
Maybe even more readible would be `\.(?:s?c|sa)ss`? – JvdV Mar 02 '22 at 08:33
-
This is the simplest one yet. I prefer `/\.(sc|sa|c)ss$/` over `/\.(?:s?c|sa)ss/` since the first is very simple. Thanks! – Kyuzu Mar 02 '22 at 08:41
Another way using alternation:
\.((?:s[ac]|c)ss)$
Here this non-capturing group (?:s[ac]|c)
will match sa
or sc
or just c
.

- 761,203
- 64
- 569
- 643
How about just
/\.(s?css|sass)$/
Regex doesn't need to be very complex to work. This is a lot easier to read for other programmers (i.e. you in about 3 months) and does the same.
Sure you can smush it more together, but why would you? Regex are complicated enough, keep 'm simple if you can :)

- 15,791
- 4
- 36
- 68
You can use
\.(?!a)(s?[ac]ss)$
See the regex demo. Details:
\.
- a dot(?!a)
- the next char cannot bea
(s?[ac]ss)
- Group 1: an optionals
,a
orc
and thenss
$
- end of string.
Another regex that can work is
\.(s(?:css|ass)|css)$
See this regex demo. Details:
\.
- a dot(s(?:css|ass)|css)
-s
and thencss
orass
orcss
$
- end of string.
NOTE: if you have a dynamic, user-defined list of such fixed strings to match after a .
at the end of string, you can build these regexes automatically using the code at the bottom of my answer.

- 607,720
- 39
- 448
- 563
You could just list the ones you want to match:
let rx = /\.css|\.sass|\.scss/; // alphabetized for future maintenance
This isn't fancy, but it is very clear and easy to add more later.
I tested it here :

- 9,936
- 10
- 57
- 97
In your pattern \.([s]?[ac]ss)$
you match .ass
because the leading s
optional and the character class [ac]
can match both characters.
Instead you could use lookarounds assertions, or use an alternation |
to allow only certain alternatives.
Some other variations could be:
\.(s?c|sa)ss$
\.
Match a.
(
Capture group 1s?c|sa
Match an optionals
then matchc
or matchsa
)
Close group 1ss$
Matchss
at the end of the string
\.(s[ac]|c)ss$
A variation on the previous pattern, now matching sa
or sc
or c
If in your environment the lookbehind assertion is supported:
\.s?[ac]ss$(?<!\.ass)
\.s?
Match a.
and optionals
[ac]
Match eithera
orc
ss$
Matchss
at the end of the string(?<!\.ass)
Negative lookbehind, assert not.ass
to the left
Note that if you want a match only, you can also use a non capture group (?:...)
instead.

- 154,723
- 16
- 55
- 70