Поскольку я не могу комментировать ответ Джаспера, я хотел бы указать на небольшую ошибку в его решении:
str.replace(/[^a-z0-9\s]/gi, '').replace(/[_\s]/g, '-');
Проблема в том, что первый код удаляет все дефисы, а затем пытаетсязаменить их :) Вы должны отменить вызовы замены, а также добавить дефис во второе регулярное выражение замены.Как это:
str.replace(/[_\s]/g, '-').replace(/[^a-z0-9-\s]/gi, '');