Note: if you don't care about an argument against the accepted answer and are just looking for an answer, then skip next section, you'll find my proposed answer at the end
the accepted answer has a few issues (in my opinion):
1) as for the first function snippet:
no regard for multiple consecutive whitespaces
input: is it a good slug
received: ---is---it---a---good---slug---
expected: is-it-a-good-slug
no regard for multiple consecutive dashes
input: -----is-----it-----a-----good-----slug-----
received: -----is-----it-----a-----good-----slug-----
expected: is-it-a-good-slug
please note that this implementation doesn't handle outer dashes (or whitespaces for that matter) whether they are multiple consecutive ones or singular characters which (as far as I understand slugs, and their usage) is not valid
2) as for the second function snippet:
it takes care of the multiple consecutive whitespaces by converting them to single -
but that's not enough as outer (at the start and end of the string) whitespaces are handled the same, so is it a good slug
would return -is-it-a-good-slug-
it also removes dashes altogether from the input which converts something like --is--it--a--good--slug--'
to isitagoodslug
, the snippet in the comment by @ryan-allen takes care of that, leaving the outer dashes issue unsolved though
now I know that there is no standard definition for slugs, and the accepted answer may get the job (that the user who posted the question was looking for) done, but this is the most popular SO question about slugs in JS, so those issues had to be pointed out, also (regarding getting the job done!) imagine typing this abomination of a URL (www.blog.com/posts/-----how-----to-----slugify-----a-----string-----
) or even just be redirected to it instead of something like (www.blog.com/posts/how-to-slugify-a-string
), I know this is an extreme case but hey that's what tests are for.
a better solution, in my opinion, would be as follows:
const slugify = str =>_x000D_
str_x000D_
.trim() // remove whitespaces at the start and end of string_x000D_
.toLowerCase() _x000D_
.replace(/^-+/g, "") // remove one or more dash at the start of the string_x000D_
.replace(/[^\w-]+/g, "-") // convert any on-alphanumeric character to a dash_x000D_
.replace(/-+/g, "-") // convert consecutive dashes to singuar one_x000D_
.replace(/-+$/g, ""); // remove one or more dash at the end of the string
_x000D_
now there is probably a RegExp ninja out there that can convert this into a one-liner expression, I'm not an expert in RegExp and I'm not saying that this is the best or most compact solution or the one with the best performance but hopefully it can get the job done.