Most common regex implementations are not composable at the language level but there are more modern alternatives like Pomsky [1] that introduce bindings and actually make regexes composable expressions.
By the way regular expressions are "composable" by definition as they are defined recursively as (in their simplest form)
- ε is the regex that matches the empty string
- given regexes A and B we can construct the new regex AB that matches first the regex A followed by B
- given regexes A and B we can construct A|B that matches A or B
- given a regex A the regex A* matches any number of repeated occurrences of A
Then for some reason languages like javascript don't provide a way of constructing
/foo/.concat(/bar/) // equivalent to /foobar/
but that is another problem.
[1]: https://pomsky-lang.org/