Jelly, 52 51 bytes
Jelly has not got one regex(s) atom
Ṫ
Ñ;”s
Ṫḣ-3
UṪw“)s(”⁼1
e€“µḣ⁴µuʠg*»Ḳ¤Ḣ‘×Ç‘
⁶;ḲÇĿ2ƤK
A full program accepting a string (using Python formatting if multiline or containing quotes) and printing the output.
How?
Ṫ - Link 1, tail: two words (list of lists)
Ṫ - tail
Ñ;”s - Link 2, tail and replace last three chars with an 's': two words (list of lists)
Ñ - call the next link (3) as a monad
”s - literal 's'
; - concatenate
Ṫḣ-3 - Link 3, tail and remove the last three chars: two words (list of lists)
Ṫ - tail
-3 - literal minus three
ḣ - head from index (1-indexed and modular)
UṪw“)s(”⁼1 - Link 4, tail ends with "(s)"?: two words (list of lists)
U - upend (reverse each word)
Ṫ - tail
“)s(” - literal [')', 's', '('] - that is "(s)" reversed
w - index of first sublist equal to that or 0 if not found
1 - literal one
⁼ - equal?
e€“µḣ⁴µuʠg*»Ḳ¤Ḣ‘×Ç‘ - Link 5, categorise: two words (list of lists)
¤ - nilad followed by link(s) as a nilad:
“µḣ⁴µuʠg*» - compression of string "a 1" + word " an" + word " one"
Ḳ - split on spaces = ["a", "1", "an", "one"]
e€ - exists in (that) for €ach (word in the two words) 1 if so, else 0
Ḣ - head (the result for the first of the two words)
‘ - increment
Ç - call the last link (4) as a monad - i.e. f(two words)
× - multiply
‘ - increment - so we have: 1 for ["1", "blah"],
- 2 for ["blah", "blah(s)"] or 3 for ["1", "blah(s)"]
⁶;ḲÇĿ2ƤK - Main link: list of characters, the string
⁶ - literal space character
; - concatenate (place a space at the beginning as we want to inspect pairs)
Ḳ - split on spaces (giving an empty list at the start)
2Ƥ - for all infixes of length two:
Ŀ - call the link at the given index as a monad:
Ç - call the last link (5) as a monad
K - join the result with spaces
- implicit print