URL-дружественные заголовки

28

Люди на этом сайте очень любят украшать свои посты ...

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

Однако, когда этот заголовок необходимо включить в URL страницы, он упрощается:

stewies-sequence

Соревнование

Ваша задача - создать программу или функцию, которая при наличии строки, представляющей заголовок записи, выводит / возвращает свое преобразование "URL-Friendly".

Алгоритм:

  • Преобразовать в нижний регистр (где применимо)
  • Замените каждый пробел ( ), точку ( .), запятую ( ,) или косую черту ( /) тире ( -)
  • Удалите все не алфавитно-цифровые символы, кроме тире.
  • Сократите группы соседних тире ( a---b -> a-b), удалите все, которые являются ведущими / завершающими.

Обратите внимание, что этот алгоритм является упрощенным и не всегда дает те же результаты, что и реальный метод сайта.


правила

  • Вы можете предположить, что вход:
    • Не будет пустым.
    • Будет содержать как минимум один буквенно-цифровой символ.
    • Будет содержать только символы в диапазоне ASCII 32-126 (для печати)
  • Полные программы или функции разрешены.
  • Встроенный модуль, который выполняет точную спецификацию задачи, не допускается.
  • Это , поэтому выигрывает самое короткое решение (в байтах)!

Тестовые случаи

Большинство сообщений на этом сайте будут служить тестами, но вот удобный список:

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
FlipTack
источник
Как насчет ведущих -с? Должны ли они быть удалены? Например asdf-, -нужно ли удалить последнее ?
Критиси Литос
Можем ли мы использовать встроенную функцию, чтобы проверить, является ли символ буквенно-цифровым, как этоif(isalphanum(ch))...
Mukul Kumar
1
@KritixiLithos Сократите группы соседних тире (a --- b -> ab), удалите все начальные / конечные.Я думаю, это должно прояснить тебя.
Мукул Кумар
А как насчет _подчеркивания? Мой код работает за исключением случаев, когда есть подчеркивание.
Критиси Литос
@ L3viathan Теперь не имеет значения, я изменил свой код, так что даже подчеркивания будут удалены
Kritixi Lithos

Ответы:

7

Retina, 33 31 байт

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

\W+
-
^-|-$

(В программе есть завершающий перевод строки)

Я не уверен, что смогу выжать из этого больше. Это должно охватывать все. Пришло похоже на Mama Fun Roll's. Еще одна 33-байтовая версия с использованием рекурсивных регулярных выражений

Попробуйте онлайн!

объяснение

T`L`l

Эта строка простая, она преобразуется в нижний регистр с помощью T ransliterating A-Z( L) в a-z( lнижний регистр).


Эта стадия проста, она, по сути, избавляет от всех ненужных персонажей, чтобы потом избавить себя от многих проблем.

[^a-z ,-9]+

[^a-z ,-9] Соответствует любому символу, который НЕ является:

  • a-z: строчный алфавит (помните, что вся строка строчная из-за предыдущего элемента)
  • : космический хаос
  • ,-9это диапазон кодов символов ,до9 который попадают ,-./0123456789именно те символы, которые нам нужны

Затем мы преобразуем все не алфавитно-цифровые символы в тире (который теперь просто и ,./-.

\W+
-

Это не будет (не) совпадение, _которое включено в \w(отрицание \W), потому что оно было удалено на предыдущем этапе

Downgoat
источник
Я думаю, что это не удастся для ввода, как a = b.
Мартин Эндер
Я действительно хочу принять это, но, как сказал Мартин, он не минимизирует соседние тире при вводе a = b:(
FlipTack
@ Flp.Tkc извините за поздний ответ (финальная неделя прямо сейчас). Мне удалось выжать еще два байта и исправить это. Я считаю, что теперь это правильно обрабатывает такие случаи
Downgoat
9

JavaScript (ES6), 90 82 79 75 байт

Это попытка сделать работу с одним replace(). Этот код извлекает только те символы, которые нас интересуют, и игнорирует все остальное. Есть некоторая дополнительная логика для обработки дефисов.

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

Контрольные примеры

Arnauld
источник
1
Ибо ,a^a,этот код дает -aa-(есть
начальные
@KritixiLithos О, спасибо за указание на это. Я не обращал внимания на это правило. Это должно быть исправлено.
Арно
9

V , 41, 40, 37 , 36 байтов

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

Попробуйте онлайн! или Проверьте все контрольные примеры сразу!

Как обычно, здесь это содержит кучу непечатных и не ASCII символов, поэтому вот 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                                -.-$

Это такие проблемы, когда система V Compressed Regex пригодится.

объяснение

Перво-наперво, мы будем преобразовывать все в нижний регистр. К счастью, есть действительно удобный способ сделать это в два байта. Я написал совет об этом здесь . Итак, мы делаем

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

После этого мы делаем кучу сжатых команд замены. Хороший обзор того, как работает сжатое регулярное выражение V, можно найти здесь , но основная идея в том, что мы можем установить старший бит, чтобы избежать экранирования определенных символов. Другое удобство заключается в том, что диапазоны (например :%) и флаги (например /g) заполняются автоматически. Но, в конце концов, все это переводится в команды vim substitute. Фактически, мы могли бы даже напрямую перевести остальную часть программы в vim. Это дало бы нам это:

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

Если вы говорите на vim-regex, должно быть более понятно, что делает остальная часть программы сейчас. Итак, остальная часть программы:

Í               " 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
источник
8

JavaScript (ES6) 91 96

1 байт сохранено thx @ETHproductions

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

Тест

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
источник
Это имеет точно такой же bytecount, что и мой ответ, если он преобразуется в именованную функцию
Kritixi Lithos
Не думайте, что вам нужно последнее *в последнем регулярном выражении, хотя я могу ошибаться
ETHproductions
Я могу ошибаться, но вы уверены, что заблаговременность необходима?
Критиси Литос
@KritixiLithos, чтобы посмотреть в будущее, нужно как минимум 1 - внутри строки, удаляя при этом все в начале и в конце
edc65
@ETHproductions верно, спасибо
edc65
4

Python 3, 103 100 96 95 байт

5 байтов сохранено благодаря Flp.Tkc

import re
lambda s,y=re.sub,d='-':y('-+',d,y('[^0-9a-z-]','',y('[ .,/]',d,s.lower()))).strip(d)
L3viathan
источник
@ Flp.Tkc Действительно ..
L3viathan
Ой, я случайно понизил это. Я не могу отменить свой голос, пока вы не отредактируете это сообщение
Kritixi Lithos
@KritixiLithos Готово
L3viathan
4

Сетчатка, 34 байта

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

\ W +
-
^ - | - $

Попробуйте онлайн!

Обратите внимание на завершающий символ новой строки. По сути, реализация ОП.

Mama Fun Roll
источник
Ссылка
TIO
Да, я только что исправил это.
Mama Fun Roll
1
Вы можете использовать, T`L`lчтобы перейти в нижний регистр с меньшим количеством байтов
Downgoat
Сбой на a..snd аналогичный
Downgoat
2
[\W]это просто\W
Мартин Эндер
3

MATL , 38 байт

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

Попробуйте онлайн! Или проверьте все тестовые случаи .

объяснение

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

Рубин , 61 60 61 64 53 байта

(52 байта кода плюс один байт для -p)

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

Попробуйте онлайн!

tr()- конвертировать символы верхнего регистра, пробел, запятую, точку и косую черту. Временно замените -пробелами, чтобы я мог использовать их stripпозже.
Обратите внимание, что -символ в "A-Z ,-/"выражении на самом деле является оператором диапазона, что также делает .символ подлежащим трансформации. Этот маневр на самом деле не сбрит байты, но он причудливый, так что он остается.

gsub(/[^\w ]/){} - удалить все символы не в разрешенном наборе.

split- технически нам не нужен этот массив, но мы splitисключаем начальные и конечные пробелы (которые фактически являются -замаскированными символами). В качестве бонуса, это сжимает воедино несколько пробелов.

*?-- стенография для .join("-"); это отменяет предыдущую splitоперацию и преобразование пробелов одновременно. Еще один байт сохраняется с использованием сокращенной нотации для символьных литералов , что делает программу требующей Ruby 1.9 или новее.

Обновление 1: Использование getsвместо режима редактирования потока Ruby экономит один байт.
Отменено согласно предложению ValueInk .

Обновление 2: (всего +3 байта)

  • Фиксированный крайний регистр ..--hi, $/(→ hi) (+10 байт) - еще раз предоставлено пользователем ValueInk
  • Взял малус за -p (+1 байт)
  • Избавился от него squeezeи использовал gsubвместо него (+2 байта) , что позволило мне:
  • Используется stripдля обработки начальных и конечных тире (-10 байт) .

Обновление 3: Хеттрик от ValueInk. Мы экономим 11 байтов, используя String#splitпривычку автоматического сжатия циклов одного и того же разделителя, что позволяет нам отбросить весь финал strip/ gsubцепочку и заменить ее на split/ joincombo. (-11 байт)

Synoli
источник
Это только возвращает строку в среде REPL и завершается ошибкой, если она запускается как правильная программа Ruby, и это не хорошо. Полные программы или функции / только лямбды. Фактически, ваша старая версия работала бы с -pфлагом, но это определенно не будет.
Value Ink
@ValueInk Вы, конечно, правы. Я изменил свое решение соответственно. Спасибо за ваш комментарий; это именно то руководство, которое я очень ценю, так как это моя первая попытка игры в гольф.
Синоли
1
Спасибо за исправление; Я удалил свое понижение. Следует отметить, что использование -pфлага неявно добавляет 1 байт к вашему коду (потому что это изменяет выполнение вашего кода с ruby -e 'your code'на ruby -pe 'your code'). Я также нашел один крайний случай, когда он дает -hi-для ввода, например, ..--hi, $/когда вы должны удалить все начальные / конечные тире и, таким образом, возвращаться hi.
Стоимость чернил
2
-2 байта, изменив gsub(/[^\w ]/){}на tr('^a-z ',''), а затем заканчивая .split*?-вместо, .strip.gsub...так как он автоматически обрабатывает дубликаты и концы строки, все за один раз!
Value Ink
1
Так как никто не сказал этого, добро пожаловать в код-гольф!
FlipTack
3

JavaScript (ES6), 74 69 байт

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>

Изменить: 5 байтов сохранены, поняв, что я уже удалил все символы, кроме -/,. 0-9a-zтого, что я могу использовать, \wчтобы соответствовать оставшиеся слова.

Нил
источник
Я думаю, что вы должны включить HTML-код в bytecount, так как он используется для решения проблемы
Kritixi Lithos
1
@KritixiLithos Нет, это только для демонстрационных целей. В вопросе говорится, что мой код может содержать хотя бы один буквенно-цифровой символ, и HTML-код просто проверяет это перед вызовом функции.
Нил
[a-z\d]может быть [^\W_]?
edc65
@ edc65 Хорошо, но потом я понял, что это может быть еще проще!
Нил
2

PHP, 87 байт

Идея регулярных выражений исходит из существующих ответов.

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

Это требует, чтобы у вас был сервер с PHP и доступ по HTTP.

Название должно быть на ключе T, а результат будет напечатан на экране.

Пример: http://localhost/title.php?T=<my shiny title>

Исмаэль Мигель
источник
2

инструменты bash / Unix, 56 байт

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

Замените прописные буквы строчными, а необходимые специальные символы - черточками.

Удалите (опция -d для tr) символы, отличные от букв, цифр и тире, а затем сожмите (опция -s для tr) нескольких тире подряд в один тире.

Удалить дефисы в начале, а затем в конце.

Митчелл Спектор
источник
2

Powershell, 85 байт

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

сделать его в нижнем регистре, а затем 3 регулярных выражений заменяет в строке, и обрезать любые хвостовых -«S

colsw
источник
может не $inputсэкономить 2 байта?
Бриантист
2

JavaScript, 90 98 94 93 91 90 91 байт

1 байт сохранен благодаря @ edc65!

1 байт сохранен благодаря @IsmaelMiguel за обнаружение ведущей точки с запятой!

1 байт, полученный после сбоя ,a-^-a,

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

Что мне больше всего нравится в этом представлении, так это диапазоны. В первом replace, мы убираем все , что не алфавитно - цифровой , а не ,, -, ., /а не пространство. Мы используем a-zдля обнаружения букв, и мы используем ,-9для обнаружения этих специальных символов и цифр, так как коды символов этих литералов ASCII все выстраиваются!

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

Kritixi Lithos
источник
Не удаляет начальные тире: «-1» становится «-1», когда оно должно стать «1».
L3viathan
@ L3viathan Должен работать сейчас
Kritixi Lithos
Не нужно считать, f=так что ваш счетчик байтов сейчас равен 96. И не нужно \ внутри диапазона в регулярном выражении, так что это может быть 95. Но ... все еще не работает: try...title
edc65
1
Hei! Я не такой старый! (65 не 64)
edc65
1
Я считаю, что вам не нужно f=и ;в конце. Просто укажите, что это анонимная функция. При этом ваш ответ должен быть длиной 90 байт.
Исмаэль Мигель
1

Луа, 91 байт

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

Где aнаходится строка URL.

Объяснение:

  • Большинство из них довольно просты. a:lower()возвращает строчную функцию
  • :gsub находит совпадение шаблона и заменяет его строкой.
  • '[ .,/]': Скобки означают «или», поэтому они соответствуют пробелу, периоду, запятой и косой черте. Не нужно быть жадным, потому что :gsubделает все случаи жизни.
  • '[^%w-]': ^означает «не» в скобках, %wозначает что-либо буквенно-цифровое. Так что '[^%w-]соответствует всему, что не буквенно-цифровое или тире.
  • '%-+': Подберите как можно больше штрихов и замените их всего одним штрихом.
  • match'%-?(.*)%-?': В Lua, если строка является единственным аргументом функции, скобки не нужны. Нужно проверить только одну черту в начале и в конце, потому что черты уже минимизированы. Нет необходимости в привязке символов, потому что .*все соответствует, жадный.
DavisDude
источник
1

C 194 байта

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

Звоните с:

int main()
{
    char *in="Loading... Forever";
    char out[128];
    f(in,out);
    puts(out);
}
Steadybox
источник
1

САС, 108

Один из менее конкурентоспособных ответов здесь из-за многословного синтаксиса SAS - штраф в 9 символов за регулярное выражение действительно причиняет боль - но это было хорошее упражнение по изучению регулярного выражения:

t=prxchange('s/^-|-$//',-1,prxchange('s/-+/-/',-1,compress(translate(lowcase(t),'----',' .,/'),'-','adk')));
user3490
источник
1

Pyth, 35 байтов

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

объяснение

    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}
bb94
источник
0

GNU Sed, 65 байт

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

Серия подстановок регулярных выражений. Использует непереносимый \Lиз GNU sed для ввода строчных букв. Запустите из файла, используя sed -f.

Джейк Кобб
источник