Titoli compatibili con URL


28

Le persone su questo sito adorano davvero abbellire i titoli dei loro post ...

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

Tuttavia, quando questo titolo deve essere incluso nell'URL della pagina, viene semplificato:

stewies-sequence

La sfida

Il tuo compito è quello di creare un programma o una funzione che, data una stringa che rappresenta un titolo del post, genera / restituisce la sua conversione "URL-Friendly".

L'algoritmo è:

  • Converti in minuscolo (ove applicabile)
  • Sostituisci ogni spazio ( ), punto ( .), virgola ( ,) o barra ( /) con un trattino ( -)
  • Rimuovi tutti i caratteri non alfanumerici, tranne i trattini.
  • Minimizza gruppi di trattini adiacenti ( a---b -> a-b), rimuovi quelli che sono in testa / in coda.

Si noti che questo algoritmo è una semplificazione e potrebbe non sempre produrre gli stessi risultati del metodo reale del sito.


Regole

  • Puoi presumere che input:
    • Non sarà vuoto.
    • Conterrà almeno un carattere alfanumerico.
    • Conterrà solo caratteri nell'intervallo ASCII 32-126 (stampabile)
  • Sono ammessi programmi o funzioni completi.
  • Un built-in che esegue la specifica esatta dell'attività non è consentito.
  • Questo è , quindi vince la soluzione più breve (in byte)!

Casi test

La maggior parte dei post su questo sito serviranno da test, ma ecco un utile elenco:

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

Alcuni più lunghi ...

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

E alcuni esempi di controllo dei casi limite (sentiti libero di suggerire di più):

0123   ->   0123
a a1   ->   a-a1
2-1=1  ->   2-11

Che dire di leader -s? Dovranno essere rimossi? Ad esempio in asdf-, l'ultimo -dovrà essere rimosso?
Kritixi Lithos,

Possiamo usare una funzione integrata per verificare se il carattere è alfanumerico in questo modoif(isalphanum(ch))...
Mukul Kumar,

1
@KritixiLithos Minimizza gruppi di trattini adiacenti (a --- b -> ab), rimuovi quelli che sono in testa / in coda. Immagino che questo dovrebbe chiarirti.
Mukul Kumar,

E i caratteri di _sottolineatura? Il mio codice funziona tranne quando ci sono caratteri di sottolineatura.
Kritixi Lithos,

@ L3viathan Non importa adesso, ho cambiato il mio codice in modo che anche i caratteri di sottolineatura vengano rimossi
Kritixi Lithos,

Risposte:


7

Retina, 33 31 byte

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

\W+
-
^-|-$

(Il programma ha una nuova riga finale)

Non sono sicuro di poterne spremere di più. Questo dovrebbe coprire tutto. È venuto simile a Mama Fun Roll's. Un'altra versione di 33 byte che utilizza regex ricorsivi

Provalo online!

Spiegazione

T`L`l

Questa linea è semplice, converte in minuscolo da T ransliterating A-Z( L) a a-z( l, minuscolo).


Questa fase è semplice, essenzialmente si sbarazza di tutti i personaggi non necessari per salvarci un sacco di problemi in seguito

[^a-z ,-9]+

[^a-z ,-9] Corrisponde a qualsiasi personaggio che NON è:

  • a-z: alfabeto minuscolo (ricorda che l'intera stringa è minuscola a causa dell'elemento precedente)
  • : carattere spaziale
  • ,-9questo è il range codice char di ,a 9che risulta essere ,-./0123456789, esattamente i caratteri che dobbiamo

Successivamente convertiamo tutti i caratteri non alfanumerici in trattini (che ora è giusto e ,./-.

\W+
-

Questo non corrisponderà (non) _che è incluso in \w(negazione di \W) perché è stato rimosso nella fase precedente


Penso che questo fallirà per input come a = b.
Martin Ender,

Voglio davvero accettarlo, ma come ha detto Martin, non si minimizzano i trattini adiacenti quando si immette a = b:(
FlipTack

@ Flp.Tkc scusa per la risposta tardiva (settimana finale in questo momento). Sono riuscito a spremere altri due byte e risolverlo. Credo che questo gestisca correttamente questi casi ora
Downgoat,

9

JavaScript (ES6), 90 82 79 75 byte

Questo è un tentativo di fare il lavoro con un singolo replace(). Questo codice estrae solo i caratteri a cui siamo interessati e ignora tutto il resto. C'è qualche logica aggiuntiva per elaborare i trattini.

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

Casi test


1
Per ,a^a,, questo codice dà -aa-(ci sono trattini
iniziali

@KritixiLithos Oh, grazie per averlo segnalato. Non ho prestato attenzione a quella regola. Questo dovrebbe essere risolto.
Arnauld,

9

V , 41, 40, 37 , 36 byte

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

Provalo online! oppure Controlla tutti i casi di test contemporaneamente!

Come al solito, qui contiene un sacco di caratteri non stampabili e non ASCII, quindi ecco un 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                                -.-$

Sono sfide come queste in cui il sistema "Compressed regex" di V è utile.

Spiegazione

Per prima cosa, convertiremo tutto in minuscolo. Fortunatamente esiste un modo davvero conveniente per farlo in due byte. Ho scritto un suggerimento al riguardo qui . Quindi lo facciamo

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

Dopodiché eseguiamo un gruppo di comandi sostitutivi compressi. Una bella panoramica di come funziona la regex compressa di V può essere trovata qui , ma l'idea di base è che possiamo impostare i bit alti per evitare di dover sfuggire a determinati personaggi. Un'altra comodità è che intervalli (come :%) e flag (come /g) vengono compilati automagicamente. Ma alla fine, tutto si traduce in comandi sostitutivi di VIM. In effetti, potremmo anche tradurre direttamente il resto del programma in vim. Questo ci darebbe questo:

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

Se parli vim-regex, dovrebbe essere più chiaro cosa fa ora il resto del programma. Quindi, ecco il resto del programma:

Í               " 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

8

JavaScript (ES6) 91 96

1 byte salvati grazie a @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)
})


Questo ha esattamente lo stesso numero della mia risposta se viene convertito in una funzione denominata
Kritixi Lithos

Non pensare di aver bisogno dell'ultimo *nell'ultima regex, anche se potrei sbagliarmi
ETHproductions

Potrei sbagliarmi, ma sei sicuro che il lookahead sia necessario?
Kritixi Lithos,

@KritixiLithos il lookahead è necessario per mantenere almeno 1 - all'interno della stringa, rimuovendo tutto all'inizio e alla fine
edc65

@ETHproductions giusto, grazie
edc65 il

4

Python 3, 103 100 96 95 byte

5 byte salvati grazie a Flp.Tkc

import re
lambda s,y=re.sub,d='-':y('-+',d,y('[^0-9a-z-]','',y('[ .,/]',d,s.lower()))).strip(d)

@ Flp.Tkc Infatti ..
L3viathan,

Oops, ho annullato il voto per errore. Non posso invertire il mio voto fino a quando non modificherai questo post
Kritixi Lithos l'

@KritixiLithos Done
L3viathan,


3

MATL , 38 byte

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

Provalo online! Oppure verifica tutti i casi di test .

Spiegazione

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

3

Rubino , 61 60 61 64 53 byte

(52 byte di codice più un byte per il -p)

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

Provalo online!

tr(... )- converte caratteri maiuscoli, spazio, virgola, punto e barra. Sostituire temporaneamente -con gli spazi bianchi in modo che possa essere utilizzato in stripseguito.
Nota il -carattere "A-Z ,-/"nell'espressione è in realtà un operatore di intervallo, il che rende il .personaggio soggetto a trasformazione. Questa manovra in realtà non si sbarazzerà dei byte, ma è elegante quindi rimane.

gsub(/[^\w ]/){} - rimuove tutti i caratteri non inclusi nel set consentito.

split- tecnicamente, non abbiamo esattamente bisogno di quell'array, ma splitelimina gli spazi iniziali e finali (che in realtà sono -personaggi mascherati). Come bonus, questo stringe insieme corse di più spazi.

*?-- Stenografia per .join("-"); ciò inverte contemporaneamente l' splitoperazione precedente e la trasformazione degli spazi bianchi. Un altro byte viene salvato utilizzando la notazione abbreviata per i caratteri letterali dei caratteri , il che rende il programma richiesto Ruby 1.9 o più recente.

Aggiornamento 1: L' uso getsdella modalità di modifica dello stream di Ruby consente di salvare un byte.
Ripristinata come da suggerimento di ValueInk .

Aggiornamento 2: (+3 byte complessivi)

  • Caso limite fisso ..--hi, $/(→ hi) (+10 byte) - ancora una volta per gentile concessione dell'utente ValueInk
  • Ho preso Malus per -p (+1 byte)
  • È stato eliminato squeezee utilizzato gsubinvece (+2 byte)Mi sono , il che mi ha permesso di:
  • Utilizzare stripper gestire i trattini iniziali e finali (-10 byte) .

Aggiornamento 3: Hattrick di ValueInk. Risparmiamo 11 byte sfruttando String#splitl'abitudine di auto-schiacciare le corse dello stesso separatore, il che ci consente di abbandonare l'intero finale strip/ gsubcatena e sostituirlo con un split/ joincombo. (-11 byte)


Questo restituisce solo la stringa in un ambiente REPL e fallisce se eseguito come un programma Ruby appropriato, e non va bene. Programmi completi o solo funzioni / lambdas. In effetti, la tua vecchia versione avrebbe funzionato con la -pbandiera, ma questo sicuramente non lo farà.
Value Ink

@ValueInk Naturalmente hai ragione. Ho modificato la mia soluzione di conseguenza. Grazie per il tuo commento; è esattamente il tipo di guida che apprezzo molto in quanto questo è il mio primo tentativo di giocare a golf.
Synoli,

1
Grazie per aver apportato la correzione; Ho rimosso il mio voto negativo. Una cosa da notare è che l'uso del -pflag aggiunge implicitamente 1 byte al codice (perché modifica l'esecuzione del codice da ruby -e 'your code'a ruby -pe 'your code'). Ho anche trovato un caso limite in cui fornisce -hi-input come ..--hi, $/quando dovresti rimuovere tutti i trattini iniziali / finali e quindi tornare hi.
Valore inchiostro

2
-2 byte cambiando gsub(/[^\w ]/){}in tr('^a-z ',''), e quindi terminando .split*?-invece di .strip.gsub...poiché gestisce automaticamente i duplicati e le estremità della stringa, tutto in una volta sola!
Valore inchiostro

1
Dal momento che nessuno lo ha detto, benvenuto a code-golf!
FlipTack,

3

JavaScript (ES6), 74 69 byte

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>

Modifica: ho salvato 5 byte rendendomi conto che avevo già eliminato tutti i caratteri tranne che -/,. 0-9a-zcosì posso usare \wper abbinare le parole rimanenti.


Penso che devi includere il codice HTML nel bytecount poiché viene utilizzato per risolvere la sfida
Kritixi Lithos,

1
@KritixiLithos No, è lì solo a scopo dimostrativo. La domanda dice che il mio codice può assumere almeno un carattere alfanumerico e il codice HTML lo verifica semplicemente prima di chiamare la funzione.
Neil,

[a-z\d]potrebbe essere [^\W_]?
edc65,

@ edc65 Bello, ma poi mi sono reso conto che potrebbe essere ancora più semplice!
Neil,

2

PHP, 87 byte

L'idea delle espressioni regolari deriva da risposte esistenti.

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

Richiede di avere un server che esegue PHP e l'accesso su HTTP.

Il titolo deve essere sul tasto Te il risultato verrà stampato sullo schermo.

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


2

strumenti bash / Unix, 56 byte

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

Sostituisci lettere maiuscole con lettere minuscole e i caratteri speciali richiesti con trattini.

Elimina (opzione -d per tr) caratteri diversi da lettere, cifre e trattini, quindi premi (opzione -s per tr) più trattini di fila in un singolo trattino.

Elimina i trattini all'inizio e poi alla fine.


2

Powershell, 85 byte

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

rendono minuscolo, quindi 3 sostituisce regex in fila, e tagliare qualsiasi trascinamento -s'


potrebbe non $inputsalvarti 2 byte?
Briantist,

2

JavaScript, 90 98 94 93 91 90 91 byte

1 byte salvato grazie a @ edc65!

1 byte salvato grazie a @IsmaelMiguel per aver individuato un punto e virgola principale!

1 byte guadagnato dopo un errore per ,a-^-a,

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

La cosa che mi piace di più di questa particolare presentazione sono gli intervalli. Nel primo replace, togliamo tutto ciò che non è alfanumerico e non una ,, -, ., /e non uno spazio. Usiamo a-zper rilevare le lettere e usiamo ,-9per rilevare quei caratteri e numeri speciali poiché i codici dei caratteri di questi letterali ASCII si allineano tutti!

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


Non rimuove i trattini iniziali: "-1" diventa "-1", quando dovrebbe diventare "1".
L3viathan,

@ L3viathan Ora dovrebbe funzionare
Kritixi Lithos il

Non è necessario contare, f=quindi il conteggio dei byte è 96 in questo momento. E non è necessario il \ all'interno di un intervallo nella regexp, quindi potrebbe essere 95. Ma ... ancora non funziona: provare...title
edc65,

1
Lui io! Non sono così vecchio! (65 non 64)
edc65,

1
Credo che non sia necessario il f=e ;alla fine. Basta specificare che questa è una funzione anonima. Con questo, la tua risposta dovrebbe essere lunga 90 byte.
Ismael Miguel,

1

Lua, 91 byte

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

Dov'è ala stringa URL.

Spiegazione:

  • La maggior parte è piuttosto semplice. a:lower()restituisce la funzione minuscola
  • :gsub trova la corrispondenza del modello e la sostituisce con la stringa.
  • '[ .,/]': Le parentesi indicano "o", quindi corrisponde a spazio, punto, virgola e barra. Non c'è bisogno di essere avidi perché :gsubfa tutte le occorrenze.
  • '[^%w-]': ^significa "non" tra parentesi, %wsignifica qualcosa alfanumerico. Quindi '[^%w-]corrisponde a tutto ciò che non lo è alfanumerico o un trattino.
  • '%-+': Abbina tutti i trattini che puoi e sostituiscili con un solo trattino.
  • match'%-?(.*)%-?': In Lua, se una stringa è l'unico argomento della funzione, non è necessaria alcuna parentesi. Deve solo controllare un trattino all'inizio e alla fine perché i trattini sono già stati ridotti a icona. Non sono necessari caratteri di ancoraggio perché .*corrisponde a tutto, goloso.

1

C, 194 byte

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

Chiama con:

int main()
{
    char *in="Loading... Forever";
    char out[128];
    f(in,out);
    puts(out);
}

1

SAS, 108

Una delle risposte meno competitive qui a causa della sintassi dettagliata di SAS - la penalità di 9 caratteri per regex fa davvero male - ma è stato un buon esercizio di apprendimento regex:

t=prxchange('s/^-|-$//',-1,prxchange('s/-+/-/',-1,compress(translate(lowcase(t),'----',' .,/'),'-','adk')));

1

Pyth, 35 byte

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

Spiegazione

    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

1

Perl 6, 75

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

0

GNU Sed, 65 byte

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

Una serie di sostituzioni regex. Utilizza non portatile \Lda GNU sed per rendere minuscolo l'input. Esegui da un file utilizzando sed -f.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.