Tytuły przyjazne adresom URL

28

Ludzie na tej stronie naprawdę lubią upiększać tytuły swoich postów ...

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

Jednak gdy tytuł ten musi być zawarty w adresie URL strony, jest uproszczony:

stewies-sequence

Wyzwanie

Twoim zadaniem jest stworzenie programu lub funkcji, która, biorąc pod uwagę ciąg znaków reprezentujący tytuł postu, wyświetla / zwraca konwersję „przyjazną adresowi URL”.

Algorytm to:

  • Konwertuj na małe litery (w stosownych przypadkach)
  • Zamień każdą spację ( ), kropkę ( .), przecinek ( ,) lub ukośnik ( /) na myślnik ( -)
  • Usuń wszystkie znaki niealfanumeryczne, z wyjątkiem myślników.
  • Zminimalizuj grupy sąsiadujących myślników ( a---b -> a-b), usuń te, które prowadzą / kończą.

Należy pamiętać, że ten algorytm jest uproszczeniem i nie zawsze może dawać takie same wyniki, jak prawdziwa metoda witryny.


Zasady

  • Możesz założyć, że dane wejściowe:
    • Nie będzie pusty.
    • Będzie zawierać co najmniej jeden znak alfanumeryczny.
    • Będzie zawierał tylko znaki z zakresu ASCII 32-126 (do wydruku)
  • Pełne programy lub funkcje są dozwolone.
  • Wbudowanym poleceniem, które ma zadanie dokładną specyfikację jest nie dozwolone.
  • To jest , więc wygrywa najkrótsze rozwiązanie (w bajtach)!

Przypadki testowe

Większość postów na tej stronie będzie służyć jako testy, ale oto przydatna lista:

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

Niektóre dłuższe ...

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

I niektóre próbki sprawdzające wielkość liter (możesz zaproponować więcej):

0123   ->   0123
a a1   ->   a-a1
2-1=1  ->   2-11
FlipTack
źródło
Co z wiodącymi -? Czy będą musiały zostać usunięte? Na przykład za asdf-czy ostatnie będą -musiały zostać usunięte?
Kritixi Lithos,
Czy możemy użyć wbudowanej funkcji, aby sprawdzić, czy znak jest alfanumeryczny w ten sposóbif(isalphanum(ch))...
Mukul Kumar
1
@KritixiLithos Zminimalizuj grupy sąsiednich myślników (a --- b -> ab), usuń wszystkie, które prowadzą / kończą. Myślę, że to powinno ci wyjaśnić.
Mukul Kumar,
A co z _podkreśleniami? Mój kod działa poza przypadkami podkreślenia.
Kritixi Lithos,
@ L3viathan Nie ma teraz znaczenia, zmieniłem kod, aby nawet podkreślenia zostały usunięte
Kritixi Lithos

Odpowiedzi:

7

Retina, 33 31 bajtów

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

\W+
-
^-|-$

(Program ma końcowy znak nowej linii)

Nie jestem pewien, czy mogę z tego wycisnąć więcej. To powinno obejmować wszystko. Przyszedł podobny do Mama Fun Roll's. Kolejna 33-bajtowa wersja z rekursywnymi wyrażeniami regularnymi

Wypróbuj online!

Wyjaśnienie

T`L`l

Ta linia jest prosta, konwertuje się na małe litery przez T ransliterating A-Z( L) na a-z( l, małe litery).


Ten etap jest prosty, zasadniczo pozbywa się wszystkich niepotrzebnych postaci, aby później zaoszczędzić sobie wielu kłopotów

[^a-z ,-9]+

[^a-z ,-9] Pasuje do każdego znaku, który NIE jest:

  • a-z: małe litery (pamiętaj, że cały ciąg jest pisany małymi literami z powodu poprzedniego elementu)
  • : znak kosmiczny
  • ,-9Zakres ten jest kod z char ,do 9których dzieje się ,-./0123456789dokładnie znaki musimy

Następnie konwertujemy wszystkie znaki alfanumeryczne na myślniki (co jest teraz sprawiedliwe i ,./-.

\W+
-

To nie będzie (nie) pasowało _do \w(uwzględnionego \W), ponieważ zostało usunięte w poprzednim etapie

Downgoat
źródło
Myślę, że to się nie powiedzie dla wejść takich jak a = b.
Martin Ender
Naprawdę chcę to zaakceptować, ale jak powiedział Martin, nie minimalizuje to sąsiednich myślników, gdy wpiszesz a = b:(
FlipTack
@ Flp.Tkc przepraszam za spóźnioną odpowiedź (teraz tydzień finałów). Udało mi się wycisnąć dwa kolejne bajty i to naprawić. Wierzę, że teraz poprawnie obsługuje takie przypadki
Downgoat
9

JavaScript (ES6), 90 82 79 75 bajtów

Jest to próba wykonania zadania za pomocą jednego replace(). Ten kod wyodrębnia tylko znaki, którymi jesteśmy zainteresowani, i ignoruje wszystko inne. Istnieje pewna dodatkowa logika przetwarzania łączników.

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

Przypadki testowe

Arnauld
źródło
1
Ponieważ ,a^a,ten kod podaje -aa-(są łączniki wiodące / końcowe)
Kritixi Lithos
@KritixiLithos Och, dzięki za zwrócenie na to uwagi. Nie zwracałem uwagi na tę zasadę. To powinno zostać naprawione.
Arnauld,
9

V , 41, 40, 37 , 36 bajtów

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

Wypróbuj online! lub Sprawdź wszystkie przypadki testowe jednocześnie!

Jak zwykle tutaj zawiera kilka znaków niedrukowalnych i nie-ASCII, więc oto zrzut heksowy:

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                                -.-$

Takie wyzwania jak te, w których przydaje się system „Compressed regex”.

Wyjaśnienie

Po pierwsze, przekonwertujemy wszystko na małe litery. Na szczęście istnieje naprawdę wygodny sposób na zrobienie tego w dwóch bajtach. Tutaj napisałem o tym wskazówkę . Tak robimy

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

Następnie wykonujemy kilka skompresowanych poleceń zastępczych. Fajny przegląd działania skompresowanego wyrażenia regularnego V można tutaj znaleźć , ale podstawową ideą jest to, że możemy ustawić wysoki bit, aby uniknąć konieczności ucieczki przed niektórymi postaciami. Inną wygodą jest to, że zakresy (podobne :%) i flagi (podobne /g) są automatycznie wypełniane. Ale ostatecznie wszystko to przekłada się na polecenia zastępujące vim. W rzeczywistości moglibyśmy nawet bezpośrednio przetłumaczyć resztę programu na vim. To dałoby nam to:

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

Jeśli mówisz vim-regex, powinno być bardziej jasne, co robi teraz reszta programu. Oto reszta programu:

Í               " 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
DJMcMayhem
źródło
8

JavaScript (ES6) 91 96

1 bajt zaoszczędzony dzięki produkcji @ETH

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
źródło
Ma dokładnie taką samą liczbę bajtów, jak moja odpowiedź, jeśli jest konwertowana na nazwaną funkcję
Kritixi Lithos,
Nie sądzę, że potrzebujesz ostatniego *w ostatnim wyrażeniu regularnym, chociaż mogę się mylić
ETHproductions
Mogę się mylić, ale czy jesteś pewien, że spojrzenie w przyszłość jest konieczne?
Kritixi Lithos,
@KritixiLithos lookahead jest konieczny, aby zachować co najmniej 1 - wewnątrz ciągu, jednocześnie usuwając wszystko na początku i na końcu
edc65
@ ETHproductions racja, dzięki
edc65
4

Python 3, 103 100 96 95 bajtów

5 bajtów zapisanych dzięki Flp.Tkc

import re
lambda s,y=re.sub,d='-':y('-+',d,y('[^0-9a-z-]','',y('[ .,/]',d,s.lower()))).strip(d)
L3viathan
źródło
@ Flp.Tkc Rzeczywiście ..
L3viathan
Ups, przypadkowo to przegłosowałem. Nie mogę cofnąć głosu, dopóki nie
zredagujesz
@KritixiLithos Done
L3viathan
4

Retina, 34 bajty

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

\ W +
-
^ - | - $

Wypróbuj online!

Zwróć uwagę na końcowy znak nowej linii. Zasadniczo wdrożenie PO.

Mama Fun Roll
źródło
Link TIO wskazuje na nieco inny kod
Kritixi Lithos
Tak, właśnie to naprawiłem.
Mama Fun Roll
1
Możesz użyć, T`L`laby przejść do małych liter z mniejszą
liczbą
Nie a..
działa
2
[\W]jest po prostu\W
Martin Ender
3

MATL , 38 bajtów

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

Wypróbuj online! Lub sprawdź wszystkie przypadki testowe .

Wyjaśnienie

'-'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
źródło
3

Rubinowy , 61 60 61 64 53 bajtów

(52 bajty kodu plus jeden bajt dla -p)

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

Wypróbuj online!

tr()- konwertuj wielkie litery, spację, przecinek, kropkę i ukośnik. Tymczasowo zamień na -biały, aby móc go strippóźniej użyć .
Zauważ, że -znak w "A-Z ,-/"wyrażeniu jest w rzeczywistości operatorem zakresu, co również powoduje, że .znak podlega transformacji. Ten manewr faktycznie nie zetrze bajtów, ale jest fantazyjny, więc może zostać.

gsub(/[^\w ]/){} - usuń wszystkie znaki spoza dozwolonego zestawu.

split- technicznie rzecz biorąc, nie potrzebujemy dokładnie tej tablicy, ale spliteliminujemy początkowe i końcowe białe spacje (które w rzeczywistości są -ukrytymi znakami). Jako bonus ściska to ciągi wielu pól.

*?-- Stenografia .join("-"); odwraca to jednocześnie poprzednią splitoperację i transformację białych znaków. Kolejny bajt jest zapisywany przy użyciu skróconej notacji literałów znakowych , co powoduje, że program wymaga Ruby 1.9 lub nowszej.

Aktualizacja 1: Użycie getszamiast trybu edycji strumienia Ruby oszczędza jeden bajt.
Powrócił jak za sugestią ValueInk użytkownika .

Aktualizacja 2: (+3 bajty ogółem)

  • Naprawiono wielkość krawędzi ..--hi, $/(→ hi) (+10 bajtów) - ponownie dzięki uprzejmości użytkownika ValueInk
  • Wzięto błąd dla -p (+1 bajt)
  • Pozbyłem się squeezei wykorzystałem gsubzamiast tego (+2 bajty) , co pozwoliło mi:
  • Służy stripdo obsługi wiodących i końcowych myślników (-10 bajtów) .

Aktualizacja 3: Hattrick firmy ValueInk. Oszczędzamy 11 bajtów, wykorzystując String#splitnawyk automatycznego ściskania przebiegów tego samego separatora, co pozwala nam porzucić cały finał strip/ gsubłańcuch i zastąpić go kombinacją split/ join. (-11 bajtów)

Synoli
źródło
Zwraca to tylko ciąg znaków w środowisku REPL i kończy się niepowodzeniem, jeśli działa jako odpowiedni program Ruby, a to nie jest dobre. Tylko pełne programy lub funkcje / lambdas. W rzeczywistości Twoja stara wersja działałaby z -pflagą, ale na pewno nie.
Wartość tuszu
@ValueInk Masz oczywiście rację. Odpowiednio zmieniłem swoje rozwiązanie. Dzięki za komentarz; właśnie takie wskazówki bardzo cenię, ponieważ jest to moja pierwsza próba gry w golfa.
Synoli,
1
Dziękujemy za dokonanie poprawki; Usunąłem moją opinię. Należy zauważyć, że użycie -pflagi niejawnie dodaje 1 bajt do kodu (ponieważ zmienia wykonanie kodu z ruby -e 'your code'na ruby -pe 'your code'). Znalazłem również jeden przypadek zbocza, w którym daje on -hi-dane wejściowe, na przykład ..--hi, $/kiedy powinieneś usunąć wszystkie wiodące / końcowe myślniki i w ten sposób powrócić hi.
Wartość tuszu
2
-2 bajty, zmieniając gsub(/[^\w ]/){}na tr('^a-z ',''), a następnie kończąc na .split*?-zamiast, .strip.gsub...ponieważ automatycznie obsługuje duplikaty i końce łańcucha, wszystko za jednym razem!
Wartość tuszu
1
Ponieważ nikt tego nie powiedział, zapraszamy do gry w golfa!
FlipTack,
3

JavaScript (ES6), 74 69 bajtów

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>

Edycja: Zapisałem 5 bajtów, wiedząc, że już usunąłem wszystkie znaki, z wyjątkiem -/,. 0-9a-ztego, że mogę użyć, \waby dopasować pozostałe słowa.

Neil
źródło
Myślę, że musisz dołączyć kod HTML do bajtu, ponieważ jest on używany do rozwiązania wyzwania
Kritixi Lithos
1
@KritixiLithos Nie, jest tam tylko w celach demonstracyjnych. Pytanie mówi, że mój kod może przyjmować co najmniej jeden znak alfanumeryczny, a kod HTML po prostu testuje to przed wywołaniem funkcji.
Neil,
[a-z\d]może być [^\W_]?
edc65
@ edc65 Fajnie, ale potem zdałem sobie sprawę, że może być jeszcze prostsze!
Neil,
2

PHP, 87 bajtów

Idea wyrażeń regularnych pochodzi z istniejących odpowiedzi.

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

Wymaga posiadania serwera z PHP i dostępu przez HTTP.

Tytuł musi znajdować się na klawiszu T, a wynik zostanie wydrukowany na ekranie.

Przykład: http://localhost/title.php?T=<my shiny title>

Ismael Miguel
źródło
2

narzędzia bash / Unix, 56 bajtów

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

Zamień wielkie litery na małe litery, a wymagane znaki specjalne na myślniki.

Usuń (-d opcję do tr) znaków innych niż litery, cyfry i myślniki, a następnie ściśnij (-s opcję do tr) wielu myślników z rzędu w jednym myślniku.

Usuń myślniki na początku, a następnie na końcu.

Mitchell Spector
źródło
2

PowerShell, 85 bajtów

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

uczynić go małymi literami, a następnie 3 regex replaces w rzędzie i przycinania wszelkie końcowe -„s

colsw
źródło
może nie $inputzaoszczędzić Ci 2 bajtów?
briantist
2

JavaScript, 90 98 94 93 91 90 91 bajtów

1 bajt zapisany dzięki @ edc65!

1 bajt zapisany dzięki @IsmaelMiguel za wykrycie wiodącego średnika!

1 bajt uzyskany po nieudanej próbie ,a-^-a,

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

Najbardziej podoba mi się to zgłoszenie. W pierwszym replace, usuwamy wszystko, co nie jest alfanumeryczny, a nie ,, -, ., /a nie przestrzeń. Używamy a-zdo wykrywania liter i ,-9wykrywamy te znaki specjalne i liczby, ponieważ kody znaków tych literałów ASCII wszystkie są w jednej linii!

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

Kritixi Lithos
źródło
Nie usuwa wiodących myślników: „-1” staje się „-1”, kiedy powinno stać się „1”.
L3viathan
@ L3viathan Powinien już działać
Kritixi Lithos
Nie trzeba liczyć, f=więc liczba bajtów wynosi teraz 96. I nie potrzeba \ wewnątrz zakresu w ...title
wyrażeniu regularnym
1
On ja! Nie jestem taka stara! (65 nie 64)
edc65
1
Wierzę, że nie trzeba f=, a ;na końcu. Po prostu określ, że jest to funkcja anonimowa. Dzięki temu Twoja odpowiedź powinna mieć długość 90 bajtów.
Ismael Miguel,
1

Lua, 91 bajtów

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

Gdzie ajest ciąg adresu URL.

Wyjaśnienie:

  • Większość jest dość prosta. a:lower()zwraca funkcję małych liter
  • :gsub znajduje dopasowanie wzorca i zastępuje go łańcuchem.
  • '[ .,/]': Nawiasy oznaczają „lub”, więc pasuje do spacji, kropki, przecinka i ukośnika. Nie trzeba być chciwym, ponieważ :gsubrobi to wszystko.
  • '[^%w-]': ^oznacza „nie” w nawiasach, %woznacza cokolwiek alfanumerycznego. '[^%w-]Dopasowuje więc wszystko, co nie jest alfanumeryczne ani myślnik.
  • '%-+': Dopasuj jak najwięcej myślników i zastąp je jednym myślnikiem.
  • match'%-?(.*)%-?': W Lua, jeśli ciąg jest jedynym argumentem funkcji, nawiasy nie są potrzebne. Wystarczy sprawdzić tylko jedną kreskę na początku i na końcu, ponieważ kreski zostały już zminimalizowane. Nie ma potrzeby używania znaków kotwicy, ponieważ .*pasuje do wszystkiego, chciwy.
DavisDude
źródło
1

C, 194 bajty

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

Zadzwoń z:

int main()
{
    char *in="Loading... Forever";
    char out[128];
    f(in,out);
    puts(out);
}
Steadybox
źródło
1

SAS, 108

Jedna z mniej konkurencyjnych odpowiedzi tutaj ze względu na pełną składnię SAS - kara 9 znaków za wyrażenie regularne naprawdę boli - ale było to dobre ćwiczenie uczenia się wyrażeń regularnych:

t=prxchange('s/^-|-$//',-1,prxchange('s/-+/-/',-1,compress(translate(lowcase(t),'----',' .,/'),'-','adk')));
użytkownik3490
źródło
1

Pyth, 35 bajtów

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

Wyjaśnienie

    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

źródło
1

Perl 6, 75

{lc .subst(/<[\ .,/]>/,"-"):g.subst(/<[\W]-[\-]>/,""):g.subst(/\-+/,"-"):g}
bb94
źródło
0

GNU Sed, 65 bajtów

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

Seria podstawień wyrażeń regularnych. Używa nieprzenośnych danych \Lz GNU sed do wprowadzania małych liter. Uruchom z pliku za pomocą sed -f.

Jake Cobb
źródło