28
\$\begingroup\$

People on this site really love to embellish their post titles...

Stewie's sequence: + * - / + * - /

However, when this title needs to be included in the page URL, it is simplified:

stewies-sequence

The Challenge

Your task is to create a program or function which, given a string representing a post title, outputs/returns its "URL-Friendly" conversion.

The algorithm is:

  • Convert to lowercase (where applicable)
  • Replace every space (), period (.), comma(,) or slash (/) with a dash (-)
  • Remove any non-alphanumeric characters, except dashes.
  • Minify groups of adjacent dashes (a---b -> a-b), remove any that are leading/trailing.

Please note that this algorithm is a simplification, and may not always produce the same results as the site's real method.


Rules

  • You can assume that input:
    • Will not be empty.
    • Will contain at least one alphanumeric character.
    • Will only contain characters in the ASCII range 32-126 (printable)
  • Full programs or functions are permitted.
  • A builtin which does the exact task specification is not permitted.
  • This is , so the shortest solution (in bytes) wins!

Test Cases

Most posts on this site will serve as tests, but here's a handy list:

Loading... Forever       -> loading-forever
N(e(s(t))) a string      -> nest-a-string
"Hello, World!"          -> hello-world
URL-Friendly titles      -> url-friendly-titles

C.U.S.R.S                -> c-u-s-r-s
1+2+3+4+...+n = -1/12?   -> 1234-n-1-12
How can I use cmp(a,b)   -> how-can-i-use-cmpa-b

Some longer ones...

Export The $PATH Variable, Line-By-Line   -> export-the-path-variable-line-by-line
Do n and n^3 have the same set of digits? -> do-n-and-n3-have-the-same-set-of-digits
Quine Anagrams! (Cops' Thread)            -> quine-anagrams-cops-thread
The Golfer Adventure - Chapter 1          -> the-golfer-adventure-chapter-1
Bootloader golf: Brainf***                -> bootloader-golf-brainf

And some edge-case checking samples (feel free to suggest more):

0123   ->   0123
a a1   ->   a-a1
2-1=1  ->   2-11
\$\endgroup\$
  • \$\begingroup\$ What about leading -s? Will they have to be removed? For example in asdf-, will the last - have to be removed? \$\endgroup\$ – user41805 Dec 10 '16 at 13:26
  • \$\begingroup\$ Can we use a built-in function to check if the char is alphanumeric like this if(isalphanum(ch))... \$\endgroup\$ – Mukul Kumar Dec 10 '16 at 13:27
  • 1
    \$\begingroup\$ @KritixiLithos Minify groups of adjacent dashes (a---b -> a-b), remove any that are leading/trailing. I guess this should make you clear. \$\endgroup\$ – Mukul Kumar Dec 10 '16 at 13:47
  • \$\begingroup\$ And what about _ underscores? My code works except when there are underscores. \$\endgroup\$ – user41805 Dec 10 '16 at 13:48
  • \$\begingroup\$ @L3viathan Doesn't matter now, I changed my code so that even underscores will be removed \$\endgroup\$ – user41805 Dec 10 '16 at 14:07

19 Answers 19

7
\$\begingroup\$

Retina, 33 31 bytes

T`L`l
[^a-z ,-9]+

\W+
-
^-|-$

(The program has a trailing newline)

I'm not sure I can squeeze more out of this. This should cover everything. Came similar to Mama Fun Roll's. Another 33 bytes version using recursive regexes

Try it online!

Explanation

T`L`l

This line is simple, it converts to lowercase by Transliterating A-Z (L) to a-z (l, lowercase).


This stage is simple, it essentially gets rid of all unneeded characters to save ourselves a lot of trouble later on

[^a-z ,-9]+

[^a-z ,-9] Matches any character that is NOT:

  • a-z: lowercase alphabet (remember entire string is lowercase because of previous item)
  • : space chacacter
  • ,-9 this is char code range of , to 9 which happens to be ,-./0123456789, exactly the characters we need

Next we convert all non alphanumeric chars to dashes (which is now just and ,./-.

\W+
-

This won't (not) match _ which is included in \w (negation of \W) because it was removed in the previous stage

|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ I think this will fail for inputs like a = b. \$\endgroup\$ – Martin Ender Dec 14 '16 at 15:44
  • \$\begingroup\$ I really want to accept this, but as martin said, it doesn't minify adjacent dashes when you input a = b :( \$\endgroup\$ – FlipTack Dec 18 '16 at 18:01
  • \$\begingroup\$ @Flp.Tkc sorry for late response (Finals week right now). I've managed to squeeze out two more bytes and fix it. I believe this correctly handles such cases now \$\endgroup\$ – Downgoat Dec 19 '16 at 2:56
9
\$\begingroup\$

JavaScript (ES6), 90 82 79 75 bytes

This is an attempt to do the job with a single replace(). This code extracts only the characters that we're interested in and ignores everything else. There's some additional logic to process the hyphens.

s=>(s.toLowerCase().replace(/[ a-z,-9]/g,c=>S=c<'0'?s+'-':s=s?S+c:c,s=0),s)

Test cases

let f =

s=>(s.toLowerCase().replace(/[ a-z,-9]/g,c=>S=c<'0'?s+'-':s=s?S+c:c,s=0),s)

console.log(f(`Loading... Forever`));                         // -> loading-forever
console.log(f(`N(e(s(t))) a string`));                        // -> nest-a-string
console.log(f(`"Hello, World!"`));                            // -> hello-world
console.log(f(`URL-Friendly titles`));                        // -> url-friendly-titles
console.log(f(`C.U.S.R.S`));                                  // -> c-u-s-r-s
console.log(f(`1+2+3+4+...+n = -1/12?`));                     // -> 1234-n-1-12
console.log(f(`How can I use cmp(a,b)`));                     // -> how-can-i-use-cmpa-b
console.log(f(`Export The $PATH Variable, Line-By-Line`));    // -> export-the-path-variable-line-by-line
console.log(f(`Do n and n^3 have the same set of digits?`));  // -> do-n-and-n3-have-the-same-set-of-digits
console.log(f(`Quine Anagrams! (Cops' Thread)`));             // -> quine-anagrams-cops-thread
console.log(f(`The Golfer Adventure - Chapter 1`));           // -> the-golfer-adventure-chapter-1
console.log(f(`Bootloader golf: Brainf***`));                 // -> bootloader-golf-brainf
console.log(f(`0123`));                                       // -> 0123
console.log(f(`a a1`));                                       // -> a-a1
console.log(f(`2-1=1`));                                      // -> 2-11
console.log(f(',a^a,'));                                      // -> aa

|improve this answer|||||
\$\endgroup\$
  • 1
    \$\begingroup\$ For ,a^a,, this code gives -aa- (there are leading/trailing hyphens) \$\endgroup\$ – user41805 Dec 10 '16 at 15:49
  • \$\begingroup\$ @KritixiLithos Oh, thanks for pointing this out. I didn't pay attention to that rule. That should be fixed. \$\endgroup\$ – Arnauld Dec 10 '16 at 16:09
9
\$\begingroup\$

V, 41, 40, 37, 36 bytes

VuÍ[ .,\/]/-
Í0-9a-z­]
Í-«/-
Í^-ü-$

Try it online! or Check all test cases at once!

As usual, here this contains a bunch of unprintable and non-ASCII characters, so here is a hexdump:

0000000: 5675 cd5b 202e 2c5c 2f5d 2f2d 0acd 8430  Vu.[ .,\/]/-...0
0000010: 2d39 612d 7aad 5d0a cd2d ab2f 2d0a cd5e  -9a-z.]..-./-..^
0000020: 2dfc 2d24                                -.-$

It's challenges like these where V's "Compressed regex" system come in handy.

Explanation

First things first, we will convert everything to lowercase. Fortunately there is a really convenient way to do this in two bytes. I wrote a tip about that here. So we do

V           " Visually select this whole line
 u          " Convert this whole line to lowercase

After that we do a bunch of compressed substitute commands. A nice overview of how V's compressed regex works can be foud here, but the basic idea is we can set the high-bit to avoid having to escape certain characters. Another convenience is that ranges (like :%) and flags (like /g) are automagically filled in. But in the end, it all translates to vim substitute commands. In fact, we could even directly translate the rest of the program to vim. That would give us this:

:%s/[ .,/]/-/g
:%s/[^0-9a-z\-]//g
:%s/-\+/-
:%s/^-\|-$//g

If you speak vim-regex, it should be more clear what the rest of the program does now. So here is the rest of the program:

Í               " Substitute:
 [ .,\/]        "   a space, period, comma or forward slash. (Due to a strange bug, this needs to be escaped)
        /-      "   with a dash
Í               " Remove:
 [^0-9a-z­]     "   Any character that is not a dash or alpha-numeric
Í               " Substitute:
 -«             "   One or more dashes
   /-           "   with one dash
Í               " Remove:
 ^-             "   A dash at the beginning of a line
   ü            "   OR
    -$          "   a dash at the end of a line
|improve this answer|||||
\$\endgroup\$
8
\$\begingroup\$

JavaScript (ES6) 91 96

1 bytes saved thx @ETHproductions

s=>s.toLowerCase().replace(/([ .,/-])|\W|_/g,(c,d)=>d?'-':'').replace(/^-*|-*$|-(?=-)/g,'')

Test

F=
s=>s.toLowerCase().replace(/([ .,/-])|\W|_/g,(c,d)=>d?'-':'').replace(/^-*|-*$|-(?=-)/g,'')

;[['Loading... Forever.....', 'loading-forever'],
['N(e(s(t))) a string', 'nest-a-string'],
['"Hello, World!"', 'hello-world'],
['URL-Friendly titles', 'url-friendly-titles'],
['C.U.S.R.S','c-u-s-r-s'],
['1+2+3+4+...+n = -1/12?', '1234-n-1-12'],
['How can I use cmp(a,b)', 'how-can-i-use-cmpa-b'],
['Export The $PATH Variable, Line-By-Line', 'export-the-path-variable-line-by-line'],
['Do n and n^3 have the same set of digits?', 'do-n-and-n3-have-the-same-set-of-digits'],
['Quine Anagrams! (Cops\' Thread)', 'quine-anagrams-cops-thread'],
['The Golfer Adventure - Chapter 1', 'the-golfer-adventure-chapter-1'],
['Bootloader golf: Brainf***', 'bootloader-golf-brainf'],
['0123', '0123'],
['a a1', 'a-a1'],
['2-1=1', '2-11']]
.forEach(t=>{
  var i=t[0],k=t[1],r=F(i)
  console.log(r==k?'OK':'KO',i+' -> '+r,r==k?'':k)
})

|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ This has exactly the same bytecount as my answer if it is converted to a named function \$\endgroup\$ – user41805 Dec 10 '16 at 14:12
  • \$\begingroup\$ Don't think you need the last * in the last regex, though I may be wrong \$\endgroup\$ – ETHproductions Dec 10 '16 at 14:27
  • \$\begingroup\$ I may be mistaken, but are you sure the lookahead is necessary? \$\endgroup\$ – user41805 Dec 10 '16 at 14:40
  • \$\begingroup\$ @KritixiLithos the lookahead is necessary to keep at least 1 - inside the string, while removing all at start and end \$\endgroup\$ – edc65 Dec 10 '16 at 14:54
  • \$\begingroup\$ @ETHproductions right, thanks \$\endgroup\$ – edc65 Dec 10 '16 at 14:55
4
\$\begingroup\$

Python 3, 103 100 96 95 bytes

5 bytes saved thanks to Flp.Tkc

import re
lambda s,y=re.sub,d='-':y('-+',d,y('[^0-9a-z-]','',y('[ .,/]',d,s.lower()))).strip(d)
|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ @Flp.Tkc Indeed.. \$\endgroup\$ – L3viathan Dec 10 '16 at 15:20
  • \$\begingroup\$ Oops, I accidentally downvoted this. I can't reverse my vote until you edit this post \$\endgroup\$ – user41805 Dec 11 '16 at 16:50
  • \$\begingroup\$ @KritixiLithos Done \$\endgroup\$ – L3viathan Dec 11 '16 at 16:51
4
\$\begingroup\$

Retina, 34 bytes

T`L`l
[^a-z\d .,/-]+

\W+
-
^-|-$

Try it online!

Note the trailing newline. Essentially the OP's implementation.

|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ The TIO link points to a slightly different code \$\endgroup\$ – user41805 Dec 10 '16 at 16:02
  • \$\begingroup\$ Yeah I just fixed it. \$\endgroup\$ – Mama Fun Roll Dec 10 '16 at 16:03
  • 1
    \$\begingroup\$ You can use T`L`l to go to lowercase with less bytes \$\endgroup\$ – Downgoat Dec 10 '16 at 18:18
  • \$\begingroup\$ Fails on a.. snd similar \$\endgroup\$ – Downgoat Dec 11 '16 at 17:32
  • 2
    \$\begingroup\$ [\W] is just \W \$\endgroup\$ – Martin Ender Dec 14 '16 at 15:39
3
\$\begingroup\$

MATL, 38 bytes

'-'jyvk45y' .,/'m(t8Y245hm)'-*'45YX6L)

Try it online! Or verify all test cases.

Explanation

'-'jyv       % Take input line. Append and prepend a dash. Gives a char column vector
k            % Convert to lowercase
45y' .,/'m(  % Replace any of ' .,/' by a dash, using assignment indexing
t8Y245hm)    % Keep only alphanumeric chars or dashes, using reference indexing
'-*'45YX     % Replace each run of dashes by a single dash, using a regular expression
6L)          % Remove first and last chars, which are always dashes. Implicitly display
|improve this answer|||||
\$\endgroup\$
3
\$\begingroup\$

Ruby, 61 60 61 64 53 bytes

(52 bytes of code plus one byte for the -p)

$_=$_.tr("A-Z ,-/","a-z ").gsub(/[^\w ]/){}.split*?-

Try it online!

tr() – convert upper case characters, space, comma, period, and slash. Temporarily substitute the - with whitespace so I can use strip later on.
Note the - character in the "A-Z ,-/" expression is actually a range operator, which also makes the . character subject to transformation. This maneuver won’t actually shave off bytes but it’s fancy so it gets to stay.

gsub(/[^\w ]/){} – remove all characters not in the allowed set.

split – technically, we don’t exactly need that array but split eliminates leading and trailing whitespace (which is actually - characters in disguise). As a bonus, this squeezes together runs of multiple spaces.

*?- – Shorthand for .join("-"); this reverses both the preceding split operation and the whitespace transformation at the same time. One more byte is saved by using the abbreviated notation for character literals, which makes the program require Ruby 1.9 or newer.

Update 1: Using gets instead of Ruby’s stream editing mode saves one byte.
Reverted as per ValueInk’s suggestion.

Update 2: (+3 bytes overall)

  • Fixed edge case ..--hi, $/ (→ hi) (+10 bytes) – once again courtesy of user ValueInk
  • Took malus for -p (+1 byte)
  • Got rid of squeeze and used gsub instead (+2 bytes), which allowed me to:
  • Use strip to handle the leading and trailing dashes (-10 bytes).

Update 3: Hattrick by ValueInk. We save 11 bytes by leveraging String#split’s habit of auto-squeezing runs of the same separator, which enables us to ditch the whole final strip/gsub chain and replace it by a split/join combo. (-11 bytes)

|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ This only returns the string in a REPL environment and fails if run as a proper Ruby program, and that's no good. Full programs or functions/lambdas only. In fact, your old version would've worked with the -p flag, but this definitely won't. \$\endgroup\$ – Value Ink Dec 11 '16 at 7:09
  • \$\begingroup\$ @ValueInk You are of course correct. I’ve changed my solution accordingly. Thanks for your comment; it is exactly the kind of guidance I appreciate a lot as this is my first attempt at golfing. \$\endgroup\$ – Synoli Dec 11 '16 at 14:54
  • 1
    \$\begingroup\$ Thank you for making the fix; I have removed my downvote. A thing to note is that using the -p flag implicitly adds 1 byte to your code (because it changes your code execution from ruby -e 'your code' to ruby -pe 'your code'). I have also found one edge case where it gives -hi- for input like ..--hi, $/ when you should be removing all leading/trailing dashes and thus be returning hi. \$\endgroup\$ – Value Ink Dec 12 '16 at 4:16
  • 2
    \$\begingroup\$ -2 bytes by changing gsub(/[^\w ]/){} to tr('^a-z ',''), and then end with .split*?- instead of .strip.gsub... since it automatically handles duplicates and the ends of the string, all in one go! \$\endgroup\$ – Value Ink Dec 12 '16 at 10:59
  • 1
    \$\begingroup\$ Since nobody said it, welcome to code-golf! \$\endgroup\$ – FlipTack Dec 12 '16 at 21:10
3
\$\begingroup\$

JavaScript (ES6), 74 69 bytes

f=
s=>s.toLowerCase().replace(/[^-/,. a-z\d]/g,``).match(/\w+/g).join`-`
<input oninput=o.textContent=/[a-z\d]/i.test(this.value)?f(this.value):``><pre id=o>

Edit: Saved 5 bytes by realising that I had already deleted all characters except -/,. 0-9a-z so I can use \w to match the remaining words.

|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ I think you have to include the HTML code into the bytecount since it is being used to solve the challenge \$\endgroup\$ – user41805 Dec 11 '16 at 7:44
  • 1
    \$\begingroup\$ @KritixiLithos No, it's only there for demonstration purposes. The question says that my code can assume at least one alphanumeric character, and the HTML code simply tests this before calling the function. \$\endgroup\$ – Neil Dec 11 '16 at 10:00
  • \$\begingroup\$ [a-z\d] could be [^\W_] ? \$\endgroup\$ – edc65 Dec 15 '16 at 11:47
  • \$\begingroup\$ @edc65 Nice, but I then realised that it could be even simpler! \$\endgroup\$ – Neil Dec 15 '16 at 19:50
2
\$\begingroup\$

PHP, 87 bytes

The idea of the regular expressions come from existing answers.

<?=trim(preg_replace(['@[^ a-z,-9]@','@[ ,-/]+@'],['','-'],strtolower($_GET[T])),'-');

It requires you to have a server running PHP, and access over HTTP.

The title must be on the key T, and the result will be printed on the screen.

Example: http://localhost/title.php?T=<my shiny title>

|improve this answer|||||
\$\endgroup\$
2
\$\begingroup\$

bash/Unix tools, 56 bytes

tr A-Z\ .,/ a-z-|tr -cds a-z0-9- -|sed s/^-//|sed s/-$//

Replace upper-case with lower-case letters, and the required special characters with dashes.

Delete (-d option to tr) characters other than letters, digits, and dashes, and then squeeze (-s option to tr) multiple dashes in a row into a single dash.

Delete dashes at the beginning, and then at the end.

|improve this answer|||||
\$\endgroup\$
2
\$\begingroup\$

Powershell, 85 Bytes

($args[0].ToLower()-replace'[ .,/]','-'-replace'[^a-z,-9]'-replace'-+','-').Trim('-')

make it lowercase, then 3 regex replaces in a row, and trim any trailing -'s

|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ mightn't $input save you 2 bytes? \$\endgroup\$ – briantist Dec 11 '16 at 22:23
2
\$\begingroup\$

JavaScript, 90 98 94 93 91 90 91 bytes

1 byte saved thanks to @edc65!

1 byte saved thanks to @IsmaelMiguel for spotting a leading semi-colon!

1 byte gained after failing for ,a-^-a,

f=s=>s.toLowerCase().replace(/[^ a-z,-9]/g,"").replace(/[ ,-/]+/g,"-").replace(/^-|-$/g,"")

The thing I like most about this particular submission are the ranges. In the first replace, we remove anything that is not alphanumeric and not a ,,-,.,/ and not a space. We use a-z for detecting the letters, and we use ,-9 to detect those special characters and numbers since the character codes of these ASCII literals all line up!

, = 44
- = 45
. = 46
/ = 47
0 = 48
...
9 = 57

f=s=>s.toLowerCase().replace(/[^ a-z,-9]/g,"").replace(/[ ,-/]+/g,"-").replace(/^-|-$/g,"")

console.log(f("---"));//TEST
console.log(f("!@#$%ˆ&*()_+"));//TEST

console.log(f("Stewie's sequence: + * - / + * - /-"));

console.log(f("Loading... Forever"));
console.log(f("N(e(s(t))) a string"));
console.log(f("\"Hello, World!\""));
console.log(f("URL-Friendly titles"));

console.log(f("C.U.S.R.S"));
console.log(f("1+2+3+4+...+n = -1/12?"));
console.log(f("How can I use cmp(a,b)"));

console.log(f("Export The $PATH Variable, Line-By-Line"));
console.log(f("Do n and n^3 have the same set of digits?"));
console.log(f("Quine Anagrams! (Cops' Thread)"));
console.log(f("The Golfer Adventure - Chapter 1"));
console.log(f("Bootloader golf: Brainf***--"));

console.log(f("0123"));
console.log(f("a a1"));
console.log(f("2-1=1"));
<input oninput=a.textContent=f(this.value)><pre id=a>

|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ Doesn't remove leading dashes: "-1" becomes "-1", when it should become "1". \$\endgroup\$ – L3viathan Dec 10 '16 at 14:08
  • \$\begingroup\$ @L3viathan Should work now \$\endgroup\$ – user41805 Dec 10 '16 at 14:11
  • \$\begingroup\$ No need to count f= so your byte count is 96 right now. And no need of the \ inside a range in the regexp, so it could be 95. But ... still not working: try ...title \$\endgroup\$ – edc65 Dec 10 '16 at 14:18
  • 1
    \$\begingroup\$ Hei! I'm not that old! (65 not 64) \$\endgroup\$ – edc65 Dec 10 '16 at 15:00
  • 1
    \$\begingroup\$ I believe you don't need the f= and the ; at the end. Just specify that this is an anonymous function. With this, your answer should be 90 bytes long. \$\endgroup\$ – Ismael Miguel Dec 10 '16 at 15:09
1
\$\begingroup\$

Lua, 91 bytes

a=a:lower():gsub( '[ .,/]', '-' ):gsub( '[^%w-]', '' ):gsub( '%-+', '-' ):match'%-?(.*)%-?'

Where a is the URL string.

Explanation:

  • Most of it's pretty straight forward. a:lower() returns the lower-case function
  • :gsub finds the match of the pattern and replaces it with the string.
  • '[ .,/]': Brackets mean "or", so this matches space, period, comma, and slash. No need to be greedy because :gsub does all occurrences.
  • '[^%w-]': ^ means "not" when inside brackets, %w means anything alphanumeric. So '[^%w-] matches anything that's not alphanumeric or a dash.
  • '%-+': Match as many dashes as you can and replace them with just one dash.
  • match'%-?(.*)%-?': In Lua, if a string is the function's only argument, no parenthesis are needed. Only needs to check for one dash at the start and end because dashes have been minimized already. No need for anchor characters because .* is match everything, greedy.
|improve this answer|||||
\$\endgroup\$
1
\$\begingroup\$

C, 194 bytes

i,j;f(char*s,char*d){if(*s>47&*s<58|*s>96&*s<123)d[i++]=*s;if(*s>64&*s<91)d[i++]=*s+32;if(i-j&&*s>43&*s<48|*s==32&&*(s+1)&&*(s+1)>47|(*(s+1)<44&&*(s+1)^32)){d[i++]=45;j=i;}*++s?f(s,d):(d[i]=0);}

Call with:

int main()
{
    char *in="Loading... Forever";
    char out[128];
    f(in,out);
    puts(out);
}
|improve this answer|||||
\$\endgroup\$
1
\$\begingroup\$

SAS, 108

One of the less competitive answers here due to the verbose syntax of SAS - the 9 character penalty per regex really hurts - but it was a good regex learning exercise:

t=prxchange('s/^-|-$//',-1,prxchange('s/-+/-/',-1,compress(translate(lowcase(t),'----',' .,/'),'-','adk')));
|improve this answer|||||
\$\endgroup\$
1
\$\begingroup\$

Pyth, 35 bytes

:r::rQ0"[-.,/]"d"[^\w ]"k6"[ -]+"\-

Explanation

    rQ0                              Convert letters to lower case
   :   "[-.,/]"d                     Replace all -.,/ with spaces
  :             "[^\w ]"k            Remove all remaining symbols
 r                       6           Remove leading and trailing spaces
:                         "[ -]+"\-  Turn runs of spaces and dashes to one dash
|improve this answer|||||
\$\endgroup\$
1
\$\begingroup\$

Perl 6, 75

{lc .subst(/<[\ .,/]>/,"-"):g.subst(/<[\W]-[\-]>/,""):g.subst(/\-+/,"-"):g}
|improve this answer|||||
\$\endgroup\$
0
\$\begingroup\$

GNU Sed, 65 bytes

s/.*/\L\0/
s@[ .,/]@-@g
s/[^-a-z0-9]//g
s/-\+/-/g
s/^-\|-$//g

A series of regex substitutions. Uses non-portable \L from GNU sed to lowercase the input. Run from a file using sed -f.

|improve this answer|||||
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.