I was also looking for a pure regex solution for something like this. I didn't find one on SO, so I worked it out.
Short version: here is the regex:
((?<====)=)|(=(?====))|((?<===)=(?==))|((?<==)=(?===))
Here is how I got there, using R:
str <- " = == === ==== ===== ====== ======="
gsub("=(?====)", "-", str, perl = TRUE) # (1) Pos. lookahead
gsub("(?<====)=", "-", str, perl = TRUE) # (2) Pos. look-behing
gsub("(?<===)=(?==)", "-", str, perl = TRUE) # (3) Middle part for cases of 4 or 5 ='s (1/2)
gsub("(?<==)=(?===)", "-", str, perl = TRUE) # (4) Middle part for cases of 4 or 5 ='s (2/2)
# Combining all, we have:
gsub("((?<====)=)|(=(?====))|((?<===)=(?==))|((?<==)=(?===))", "-", str, perl = TRUE) # (5)
(1) = == === -=== --=== ---=== ----===
(2) = == === ===- ===-- ===--- ===----
(3) = == === ==-= ==--= ==---= ==----=
(4) = == === =-== =--== =---== =----==
(5) = == === ---- ----- ------ -------
Alternative method for a less convoluted regex (but requires 3 steps)
# First, deal with 4 & 5 equal signs with negative look-behind and lookahead
str <- gsub("(?<!=)={4}(?!=)", "----", str, perl = TRUE) # (2.1)
str <- gsub("(?<!=)={5}(?!=)", "-----", str, perl = TRUE) # (2.2)
# Then use regex (3) from above for 6+ equal signs
str <- gsub("((?<====)=)|(=(?====))", "-", str, perl = TRUE) # (2.3)
(2.1) = == === ---- ===== ====== =======
(2.2) = == === ---- ----- ====== =======
(2.3) = == === ---- ----- ------ -------