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

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


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


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

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


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)

@ Flp.Tkc Rzeczywiście ..
L3viathan

Ups, przypadkowo to przegłosowałem. Nie mogę cofnąć głosu, dopóki nie
zredagujesz

@KritixiLithos Done
L3viathan


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

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)


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.


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>


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.


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


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


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.

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

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

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

1

Perl 6, 75

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

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.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.