Although the solution (word boundaries) is an old classic, yours is an interesting question because the words in the alternation are so similar.
You can start with this:
\b(?:abs|acos|acosh|asin|asinh|atan|atanh)\b
And compress to that:
\b(?:a(?:cosh?|sinh?|tanh?|bs))\b
How does it work?
- The key idea is to use the word boundaries
\b
to ensure that the match is not embedded in a larger word.
- The idea of the compression is to make the engine match faster. It's hard to read, though, so unless you need every last drop of performance, that's purely for entertainment purposes.
Token-By-Token
\b # the boundary between a word char (\w) and
# something that is not a word char
(?: # group, but do not capture:
a # 'a'
(?: # group, but do not capture:
cos # 'cos'
h? # 'h' (optional (matching the most
# amount possible))
| # OR
sin # 'sin'
h? # 'h' (optional (matching the most
# amount possible))
| # OR
tan # 'tan'
h? # 'h' (optional (matching the most
# amount possible))
| # OR
bs # 'bs'
) # end of grouping
) # end of grouping
\b # the boundary between a word char (\w) and
# something that is not a word char
Bonus Regex
In case you're feeling depressed today, this alternate compression (is it longer than the original?) should cheer you up.
\b(?:a(?:(?:co|b)s|(?:cos|(?:si|ta)n)h|(?:si|ta)n))\b