Опция, использующая группу захвата и обратную ссылку, может быть:
(?<!\S)(\w{2,3})(?:-\1)*-(\w+)(?!\S)
Это будет соответствовать:
(?<!\S)
Отрицательный вид сзади, утверждают, что слеване символ без пробела (\w{2,3})
Захват в группе 1 два или три раза слово char (?:-\1)*
Повторите 0+ раз, сопоставляя дефис с последующей обратной ссылкой на то, что сопоставлено вгруппа 1 -(\w+)
Совпадение -
, за которым следует сопоставление символов 1+ в группе 2 (?!\S)
Отрицательный взгляд вперед, утверждайте, что справа не является непробельным символом
При замене используйте вторую группу захвата \\2
или r'\2
Regex demo | Python demo
Например
import re
text = "c-c-c-c-come oh-oh-oh-oh it's a bad life oh-oh-oh-oh"
pattern = r"(?<!\S)(\w{1,3})(?:-\1)*-(\w+)(?!\S)"
text = re.sub(pattern, r'\2', text)
print(text)
Результат
come oh it's a bad life oh