You can use re.sub
to insert that space:
re.sub(r'\b(?:(\D+)(\d+)|(\d+)(\D+))\b', r"\1\3 \2\4", word)
This matches digits followed by non-digits or vice-versa.
The \b
boundaries make sure the word is matched in its entirety, so that we don't match numbers in the middle of a word.
The replacement pattern \1\3 \2\4
takes advantage of the fact that unmatched groups are replaced with the empty string. We know that either group 1 and 2 or group 3 and 4 will match, and the other groups will be empty, so \1\3 \2\4
will always produce a valid result (without duplicating any part of the input).
Examples:
>>> re.sub(r'\b(?:(\D+)(\d+)|(\d+)(\D+))\b', r"\1\3 \2\4", "abc12")
'abc 12'
>>> re.sub(r'\b(?:(\D+)(\d+)|(\d+)(\D+))\b', r"\1\3 \2\4", "12abc")
'12 abc'
>>> re.sub(r'\b(?:(\D+)(\d+)|(\d+)(\D+))\b', r"\1\3 \2\4", "a12bc")
'a12bc'