Convert string to spinal case
This does it in two steps:


Add spaces before each uppercase, which allows the uppercases to be handled by...
The delimiter case.  This is the same regex you already wrote, although I am collapsing multiple delimters down to a single one.


Having two transformation passes, similar to using a unix pipeline, is easier to reason about that breaking it up into two cases with an "if else".

Note the cryptic (?!^) matches "not at the beginning of a line" only

function spinalCase(str) {
  return str.replace(/(?!^)([A-Z])/g, ' $1')
            .replace(/[_\s]+(?=[a-zA-Z])/g, '-').toLowerCase();
}


All of your test cases pass:

this-is-spinal-tap
this-is-spinal-tap
the-andy-griffith-show
teletubbies-say-eh-oh