You could use re.finditer to retrieve the start/end of all possible matches and do an appropriate replacement. This will cover variable length replacing, but does mean you need to be wary of re syntax for the frm argument.
import re
from random import choice
def replace_random(src, frm, to):
matches = list(re.finditer(frm, src))
replace = choice(matches)
return src[:replace.start()] + to + src[replace.end():]
Example:
>>> [replace_random('x x x x x', r'\bx\b', 'y') for _ in range(10)]
['y x x x x', 'x x x x y', 'x x y x x', 'x y x x x', 'x x x y x', 'x x x y x', 'x x y x x', 'x y x x x', 'x x x x y', 'x x y x x']
xx,yy, ...) always separated by exactly one space?