URL-Friendly Titles

28

3

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

FlipTack

Posted 2016-12-10T13:03:50.893

Reputation: 13 242

What about leading -s? Will they have to be removed? For example in asdf-, will the last - have to be removed? – user41805 – 2016-12-10T13:26:11.103

Can we use a built-in function to check if the char is alphanumeric like this if(isalphanum(ch))... – Mukul Kumar – 2016-12-10T13:27:45.630

1@KritixiLithos Minify groups of adjacent dashes (a---b -> a-b), remove any that are leading/trailing. I guess this should make you clear. – Mukul Kumar – 2016-12-10T13:47:16.237

And what about _ underscores? My code works except when there are underscores. – user41805 – 2016-12-10T13:48:17.027

@L3viathan Doesn't matter now, I changed my code so that even underscores will be removed – user41805 – 2016-12-10T14:07:47.497

@MukulKumar yes, that's fine. A built-in is only disallowed if it completes this exact algorithm. – FlipTack – 2016-12-10T14:36:14.267

@KritixiLithos I just did some poking around and it looks like they actually create dashes,, but because I don't want to invalidate answers, so I'll accept any behaviour with underscores. – FlipTack – 2016-12-10T14:39:24.520

Anything about underscores? – OldBunny2800 – 2016-12-10T16:24:47.097

@OldBunny2800 you can either replace them with a dash or treat them as invalid characters. really they should create dashes but I don't want to invalidate all the answers by changing the rules now. – FlipTack – 2016-12-10T16:36:08.897

Answers

7

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

Downgoat

Posted 2016-12-10T13:03:50.893

Reputation: 27 116

I think this will fail for inputs like a = b. – Martin Ender – 2016-12-14T15:44:22.223

I really want to accept this, but as martin said, it doesn't minify adjacent dashes when you input a = b :( – FlipTack – 2016-12-18T18:01:16.283

@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 – Downgoat – 2016-12-19T02:56:53.147

9

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

Arnauld

Posted 2016-12-10T13:03:50.893

Reputation: 111 334

1For ,a^a,, this code gives -aa- (there are leading/trailing hyphens) – user41805 – 2016-12-10T15:49:54.597

@KritixiLithos Oh, thanks for pointing this out. I didn't pay attention to that rule. That should be fixed. – Arnauld – 2016-12-10T16:09:53.737

9

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

James

Posted 2016-12-10T13:03:50.893

Reputation: 54 537

8

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)
})

edc65

Posted 2016-12-10T13:03:50.893

Reputation: 31 086

This has exactly the same bytecount as my answer if it is converted to a named function – user41805 – 2016-12-10T14:12:37.227

Don't think you need the last * in the last regex, though I may be wrong – ETHproductions – 2016-12-10T14:27:21.720

I may be mistaken, but are you sure the lookahead is necessary? – user41805 – 2016-12-10T14:40:04.933

@KritixiLithos the lookahead is necessary to keep at least 1 - inside the string, while removing all at start and end – edc65 – 2016-12-10T14:54:34.960

@ETHproductions right, thanks – edc65 – 2016-12-10T14:55:14.717

4

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)

L3viathan

Posted 2016-12-10T13:03:50.893

Reputation: 3 151

@Flp.Tkc Indeed.. – L3viathan – 2016-12-10T15:20:06.707

Oops, I accidentally downvoted this. I can't reverse my vote until you edit this post – user41805 – 2016-12-11T16:50:39.230

@KritixiLithos Done – L3viathan – 2016-12-11T16:51:12.833

4

Retina, 34 bytes

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

\W+
-
^-|-$

Try it online!

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

Mama Fun Roll

Posted 2016-12-10T13:03:50.893

Reputation: 7 234

The TIO link points to a slightly different code – user41805 – 2016-12-10T16:02:41.597

Yeah I just fixed it. – Mama Fun Roll – 2016-12-10T16:03:16.163

1You can use T\L`l` to go to lowercase with less bytes – Downgoat – 2016-12-10T18:18:23.263

Fails on a.. snd similar – Downgoat – 2016-12-11T17:32:35.360

fixed @Downgoat – Mama Fun Roll – 2016-12-11T17:43:39.473

This doesn't work for the 1+2+3+4+n = - 1/12 test case, but this should cover you (and save a byte)!

– Dom Hastings – 2016-12-12T13:43:04.777

2[\W] is just \W – Martin Ender – 2016-12-14T15:39:31.693

3

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

Luis Mendo

Posted 2016-12-10T13:03:50.893

Reputation: 87 464

3

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.

Neil

Posted 2016-12-10T13:03:50.893

Reputation: 95 035

I think you have to include the HTML code into the bytecount since it is being used to solve the challenge – user41805 – 2016-12-11T07:44:29.110

1@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. – Neil – 2016-12-11T10:00:59.290

[a-z\d] could be [^\W_] ? – edc65 – 2016-12-15T11:47:39.813

@edc65 Nice, but I then realised that it could be even simpler! – Neil – 2016-12-15T19:50:25.343

3

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)

Synoli

Posted 2016-12-10T13:03:50.893

Reputation: 141

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. – Value Ink – 2016-12-11T07:09:15.010

@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. – Synoli – 2016-12-11T14:54:06.013

1Thank 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. – Value Ink – 2016-12-12T04:16:40.427

@ValueInk Thanks once again. I have edited my answer to fix both issues. – Synoli – 2016-12-12T08:43:42.900

2-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! – Value Ink – 2016-12-12T10:59:20.280

@ValueInk Regarding that tr: unfortunately, we’re supposed to preserve the digits (the \w regexp covers that); another possible variation of tr('^a-z0-9','') would actually add one byte to the tally.
The split/join combo is brilliant though. Thanks – this saved a whopping 11 bytes!
– Synoli – 2016-12-12T12:53:59.313

1Since nobody said it, welcome to code-golf! – FlipTack – 2016-12-12T21:10:37.047

2

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>

user41805

Posted 2016-12-10T13:03:50.893

Reputation: 16 320

Doesn't remove leading dashes: "-1" becomes "-1", when it should become "1". – L3viathan – 2016-12-10T14:08:28.137

@L3viathan Should work now – user41805 – 2016-12-10T14:11:55.380

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 – edc65 – 2016-12-10T14:18:33.967

@edc65 I have edited it so it should work now. Also, thanks for the tip for removing the \\ :) – user41805 – 2016-12-10T14:33:34.803

1Hei! I'm not that old! (65 not 64) – edc65 – 2016-12-10T15:00:02.923

1I 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. – Ismael Miguel – 2016-12-10T15:09:34.110

@IsmaelMiguel Thanks for spotting the lone ;! But the reason I don't use anonymous functions is because I personally detest them – user41805 – 2016-12-10T15:14:35.630

Then why did you used one? – Ismael Miguel – 2016-12-10T15:26:27.767

Here, a shorter one: f=s=>s.toLowerCase().replace(/[ ,-/]+/g,"-").replace(/^-|-$|[^ a-z,-9]/g,""). I've moved the 1st RegExp into the last. – Ismael Miguel – 2016-12-10T15:34:45.023

@IsmaelMiguel Doesn't work for a-^-a, it gives a--a. That is why I ordered my regexps in that order – user41805 – 2016-12-10T15:40:25.380

Makes sense. I really didnt test with that. – Ismael Miguel – 2016-12-10T15:42:08.793

2

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>

Ismael Miguel

Posted 2016-12-10T13:03:50.893

Reputation: 6 797

2

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.

Mitchell Spector

Posted 2016-12-10T13:03:50.893

Reputation: 3 392

2

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

colsw

Posted 2016-12-10T13:03:50.893

Reputation: 3 195

mightn't $input save you 2 bytes? – briantist – 2016-12-11T22:23:27.723

1

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.

DavisDude

Posted 2016-12-10T13:03:50.893

Reputation: 293

1

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);
}

Steadybox

Posted 2016-12-10T13:03:50.893

Reputation: 15 798

1

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')));

user3490

Posted 2016-12-10T13:03:50.893

Reputation: 809

1

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

user48543

Posted 2016-12-10T13:03:50.893

Reputation:

1

Perl 6, 75

{lc .subst(/<[\ .,/]>/,"-"):g.subst(/<[\W]-[\-]>/,""):g.subst(/\-+/,"-"):g}

bb94

Posted 2016-12-10T13:03:50.893

Reputation: 1 831

0

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.

Jake Cobb

Posted 2016-12-10T13:03:50.893

Reputation: 220