Titres compatibles avec les URL

28

Les gens sur ce site aiment vraiment embellir leurs titres de poste ...

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

Cependant, lorsque ce titre doit être inclus dans l'URL de la page, il est simplifié:

stewies-sequence

Le défi

Votre tâche consiste à créer un programme ou une fonction qui, étant donné une chaîne représentant un titre de publication, génère / renvoie sa conversion "URL-Friendly".

L'algorithme est:

  • Convertir en minuscules (le cas échéant)
  • Remplacez chaque espace ( ), point ( .), virgule ( ,) ou barre oblique ( /) par un tiret ( -)
  • Supprimez tous les caractères non alphanumériques, à l'exception des tirets.
  • Réduisez les groupes de tirets adjacents ( a---b -> a-b), supprimez ceux qui mènent / suivent.

Veuillez noter que cet algorithme est une simplification et peut ne pas toujours produire les mêmes résultats que la méthode réelle du site.


Règles

  • Vous pouvez supposer que l'entrée:
    • Ne sera pas vide.
    • Contiendra au moins un caractère alphanumérique.
    • Ne contiendra que des caractères dans la plage ASCII 32-126 (imprimable)
  • Les programmes ou fonctions complets sont autorisés.
  • Un builtin qui fait la spécification de tâche exacte n'est pas autorisé.
  • Il s'agit de , donc la solution la plus courte (en octets) l'emporte!

Cas de test

La plupart des messages sur ce site serviront de tests, mais voici une liste pratique:

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

Certains plus longs ...

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

Et quelques échantillons de vérification de bord (n'hésitez pas à suggérer plus):

0123   ->   0123
a a1   ->   a-a1
2-1=1  ->   2-11
FlipTack
la source
Et les leaders -? Devront-ils être supprimés? Par exemple dans asdf-, le dernier -devra-t-il être supprimé?
Kritixi Lithos
Pouvons-nous utiliser une fonction intégrée pour vérifier si le caractère est alphanumérique comme celui-ciif(isalphanum(ch))...
Mukul Kumar
1
@KritixiLithos Réduisez les groupes de tirets adjacents (a --- b -> ab), supprimez ceux qui mènent / suivent. Je suppose que cela devrait vous éclairer.
Mukul Kumar
Et qu'en est-il des _soulignements? Mon code fonctionne sauf lorsqu'il y a des traits de soulignement.
Kritixi Lithos
@ L3viathan Peu importe maintenant, j'ai changé mon code afin que même les
traits de

Réponses:

7

Rétine, 33 31 octets

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

\W+
-
^-|-$

(Le programme a une nouvelle ligne de fin)

Je ne suis pas sûr de pouvoir en tirer davantage. Cela devrait couvrir tout. Entré similaire à Mama Fun Roll's. Une autre version de 33 octets utilisant des expressions rationnelles récursives

Essayez-le en ligne!

Explication

T`L`l

Cette ligne est simple, elle se transforme en minuscule par T ransliterating A-Z( L) en a-z( l, minuscule).


Cette étape est simple, elle se débarrasse essentiellement de tous les personnages inutiles pour nous éviter beaucoup de problèmes plus tard

[^a-z ,-9]+

[^a-z ,-9] Correspond à tout caractère qui n'est PAS:

  • a-z: alphabet minuscule (rappelez-vous que la chaîne entière est en minuscule à cause de l'élément précédent)
  • : espace chacacter
  • ,-9il s'agit de la plage de codes de caractères ,à 9laquelle il se trouve ,-./0123456789, exactement les caractères dont nous avons besoin

Ensuite, nous convertissons tous les caractères non alphanumériques en tirets (ce qui est maintenant juste et ,./-.

\W+
-

Cela ne correspondra pas (pas) à _ce qui est inclus dans \w(négation de \W) car il a été supprimé à l'étape précédente

Downgoat
la source
Je pense que cela échouera pour des entrées comme a = b.
Martin Ender
Je veux vraiment accepter cela, mais comme Martin l'a dit, cela ne réduit pas les tirets adjacents lorsque vous entrez a = b:(
FlipTack
@ Flp.Tkc désolé pour une réponse tardive (semaine des finales en ce moment). J'ai réussi à extraire deux octets supplémentaires et à le corriger. Je crois que cela gère correctement ces cas maintenant
Downgoat
9

JavaScript (ES6), 90 82 79 75 octets

Il s'agit d'une tentative de faire le travail avec un seul replace(). Ce code extrait uniquement les caractères qui nous intéressent et ignore tout le reste. Il y a une logique supplémentaire pour traiter les tirets.

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

Cas de test

Arnauld
la source
1
Pour ,a^a,, ce code donne -aa-(il y a des tirets de tête / de fin)
Kritixi Lithos
@KritixiLithos Oh, merci de l'avoir signalé. Je n'ai pas fait attention à cette règle. Cela devrait être corrigé.
Arnauld
9

V , 41, 40, 37 , 36 octets

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

Essayez-le en ligne! ou Vérifiez tous les cas de test à la fois!

Comme d'habitude, ici cela contient un tas de caractères non imprimables et non ASCII, voici donc 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                                -.-$

Ce sont des défis comme ceux-ci où le système "Compression regex" de V est utile.

Explication

Tout d'abord, nous allons tout convertir en minuscules. Heureusement, il existe un moyen très pratique de le faire en deux octets. J'ai écrit un conseil à ce sujet ici . Donc on fait

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

Après cela, nous faisons un tas de commandes de substitution compressées. Un bon aperçu du fonctionnement des expressions rationnelles compressées de V peut être ici , mais l'idée de base est que nous pouvons définir le bit haut pour éviter d'avoir à échapper à certains caractères. Une autre commodité est que les plages (comme :%) et les drapeaux (comme /g) sont remplis automatiquement. Mais au final, tout cela se traduit par des commandes de substitution vim. En fait, nous pourrions même traduire directement le reste du programme en vim. Cela nous donnerait ceci:

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

Si vous parlez vim-regex, il devrait être plus clair ce que fait le reste du programme maintenant. Voici donc le reste du programme:

Í               " 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
la source
8

JavaScript (ES6) 91 96

1 octet enregistré thx @ETHproductions

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

Tester

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
la source
Cela a exactement le même nombre d'octets que ma réponse s'il est converti en une fonction nommée
Kritixi Lithos
Ne pensez pas que vous avez besoin du dernier *dans la dernière expression régulière, bien que je puisse me tromper
ETHproductions
Je me trompe peut-être, mais êtes-vous sûr que l'anticipation est nécessaire?
Kritixi Lithos
@KritixiLithos le lookahead est nécessaire pour garder au moins 1 - à l'intérieur de la chaîne, tout en supprimant tout au début et à la fin
edc65
@ETHproductions à droite, merci
edc65
4

Python 3, 103 100 96 95 octets

5 octets enregistrés grâce à Flp.Tkc

import re
lambda s,y=re.sub,d='-':y('-+',d,y('[^0-9a-z-]','',y('[ .,/]',d,s.lower()))).strip(d)
L3viathan
la source
@ Flp.Tkc En effet ..
L3viathan
Oups, j'ai accidentellement rétrogradé cela. Je ne peux pas inverser mon vote tant que vous n'avez pas
modifié
@KritixiLithos Done
L3viathan
4

Rétine, 34 octets

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

\ W +
-
^ - | - $

Essayez-le en ligne!

Notez la nouvelle ligne de fin. Essentiellement la mise en œuvre du PO.

Mama Fun Roll
la source
Le lien TIO pointe vers un code légèrement différent
Kritixi Lithos
Ouais je viens de le réparer.
Mama Fun Roll
1
Vous pouvez utiliser T`L`lpour passer en minuscules avec moins d'octets
Downgoat
Échoue sur a..snd similaire
Downgoat
2
[\W]est juste\W
Martin Ender
3

MATL , 38 octets

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

Essayez-le en ligne! Ou vérifiez tous les cas de test .

Explication

'-'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
la source
3

Rubis , 61 60 61 64 53 octets

(52 octets de code plus un octet pour le -p)

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

Essayez-le en ligne!

tr()- convertissez les majuscules, l'espace, la virgule, le point et la barre oblique. Remplacez temporairement le -avec un espace afin que je puisse l'utiliser stripplus tard.
Notez que le -caractère dans l' "A-Z ,-/"expression est en fait un opérateur de plage, ce qui rend également le. soumet caractère à une transformation. Cette manœuvre ne rasera pas réellement les octets, mais elle est fantaisiste, elle doit donc rester.

gsub(/[^\w ]/){} - supprimez tous les caractères ne figurant pas dans l'ensemble autorisé.

split- techniquement, nous n'avons pas exactement besoin de ce tableau mais splitéliminons les espaces blancs de début et de fin (qui sont en fait des -caractères déguisés). En prime, cela serre des séries de plusieurs espaces.

*?-- Sténographie pour .join("-"); cela inverse à la fois l' splitopération précédente et la transformation des espaces blancs. Un octet de plus est enregistré en utilisant la notation abrégée pour les littéraux de caractères , ce qui rend le programme nécessite Ruby 1.9 ou plus récent.

Mise à jour 1: l' utilisation getsau lieu du mode d'édition de flux de Ruby permet d'économiser un octet.
Revenu selon la suggestion de ValueInk .

Mise à jour 2: (+3 octets au total)

  • Cas de bord fixe ..--hi, $/(→ hi) (+10 octets) - avec l'aimable autorisation de l'utilisateur ValueInk
  • A pris du malus pour -p (+1 octet)
  • Débarrassé squeezeet utilisé à la gsubplace (+2 octets) , ce qui m'a permis de:
  • Utilisez strippour gérer les tirets de début et de fin (-10 octets) .

Mise à jour 3: Hattrick par ValueInk. Nous économisons 11 octets en tirant parti String#splitde l'habitude de compression automatique des séquences du même séparateur, ce qui nous permet d'abandonner la chaîne strip/ finale complète gsubet de la remplacer par un combo split/ join. (-11 octets)

Synoli
la source
Cela renvoie uniquement la chaîne dans un environnement REPL et échoue s'il est exécuté en tant que programme Ruby approprié, et ce n'est pas bon. Programmes ou fonctions complets / lambdas uniquement. En fait, votre ancienne version aurait fonctionné avec le -pdrapeau, mais ce ne sera certainement pas le cas.
Value Ink
@ValueInk Vous avez bien sûr raison. J'ai changé ma solution en conséquence. Merci pour votre commentaire; c'est exactement le genre de conseils que j'apprécie beaucoup car c'est ma première tentative de golf.
Synoli
1
Merci d'avoir fait le correctif; J'ai supprimé mon downvote. Une chose à noter est que l'utilisation de l' -pindicateur ajoute implicitement 1 octet à votre code (car il change l'exécution de votre code de ruby -e 'your code'à ruby -pe 'your code'). J'ai également trouvé un cas de bord où il donne -hi-une entrée comme ..--hi, $/lorsque vous devriez supprimer tous les tirets de tête / de fin et donc revenir hi.
Value Ink
2
-2 octets en changeant gsub(/[^\w ]/){}en tr('^a-z ',''), puis se terminent par .split*?-au lieu de .strip.gsub...car il gère automatiquement les doublons et les extrémités de la chaîne, tout d'un coup!
Value Ink
1
Puisque personne ne l'a dit, bienvenue au code-golf!
FlipTack
3

JavaScript (ES6), 74 69 octets

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: sauvé 5 octets en réalisant que j'avais déjà supprimé tous les caractères sauf -/,. 0-9a-zpour que je puisse utiliser \wpour faire correspondre les mots restants.

Neil
la source
Je pense que vous devez inclure le code HTML dans le bytecount car il est utilisé pour résoudre le défi
Kritixi Lithos
1
@KritixiLithos Non, il n'est là qu'à des fins de démonstration. La question dit que mon code peut prendre au moins un caractère alphanumérique et que le code HTML le teste simplement avant d'appeler la fonction.
Neil
[a-z\d]pourrait être [^\W_]?
edc65
@ edc65 Nice, mais j'ai alors réalisé que cela pourrait être encore plus simple!
Neil
2

PHP, 87 octets

L'idée des expressions régulières vient des réponses existantes.

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

Cela nécessite que vous ayez un serveur exécutant PHP et un accès via HTTP.

Le titre doit être sur la clé Tet le résultat sera imprimé à l'écran.

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

Ismael Miguel
la source
2

outils bash / Unix, 56 octets

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

Remplacez les majuscules par des lettres minuscules et les caractères spéciaux requis par des tirets.

Supprimez (option -d à tr) des caractères autres que des lettres, des chiffres et des tirets, puis serrez (option -s à tr) plusieurs tirets d'affilée dans un seul tiret.

Supprimez les tirets au début, puis à la fin.

Mitchell Spector
la source
2

Powershell, 85 octets

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

faire en minuscule, puis 3 remplace regex dans une rangée, et découpez tous les traînants -s »

colsw
la source
pourrait ne pas $inputvous faire économiser 2 octets?
briantist
2

JavaScript, 90 98 94 93 91 90 91 octets

1 octet enregistré grâce à @ edc65!

1 octet économisé grâce à @IsmaelMiguel pour avoir repéré un point-virgule de tête!

1 octet gagné après avoir échoué ,a-^-a,

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

Ce que j'aime le plus dans cette présentation, ce sont les plages. Dans le premier replace, on enlève tout ce qui est non alphanumérique et non un ,, -, ., /et non un espace. Nous utilisons a-zpour détecter les lettres, et nous utilisons ,-9pour détecter ces caractères spéciaux et ces chiffres puisque les codes de caractères de ces littéraux ASCII sont tous alignés!

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

Kritixi Lithos
la source
Ne supprime pas les tirets principaux: "-1" devient "-1", alors qu'il devrait devenir "1".
L3viathan
@ L3viathan Devrait fonctionner maintenant
Kritixi Lithos
Pas besoin de compter f=donc votre nombre d'octets est de 96 en ce moment. Et pas besoin de \ dans une plage dans l'expression rationnelle, il pourrait donc être 95. Mais ... ne fonctionne toujours pas: essayez...title
edc65
1
Il je! Je ne suis pas si vieux! (65 pas 64)
edc65
1
Je crois que vous n'avez pas besoin du f=et ;du final. Précisez simplement qu'il s'agit d'une fonction anonyme. Avec cela, votre réponse devrait être longue de 90 octets.
Ismael Miguel
1

Lua, 91 octets

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

aest la chaîne URL.

Explication:

  • La plupart est assez simple. a:lower()renvoie la fonction minuscule
  • :gsub trouve la correspondance du modèle et le remplace par la chaîne.
  • '[ .,/]': Les crochets signifient "ou", donc cela correspond à l'espace, à la période, à la virgule et à la barre oblique. Pas besoin d'être gourmand car :gsubfait toutes les occurrences.
  • '[^%w-]': ^signifie "non" quand entre parenthèses, %wsignifie n'importe quoi alphanumérique. Correspond donc à '[^%w-]tout ce qui n'est pas alphanumérique ou un tiret.
  • '%-+': Faites correspondre autant de tirets que possible et remplacez-les par un seul tiret.
  • match'%-?(.*)%-?': Dans Lua, si une chaîne est le seul argument de la fonction, aucune parenthèse n'est nécessaire. Il suffit de vérifier un tiret au début et à la fin car les tirets ont déjà été minimisés. Pas besoin de personnages d'ancrage car .*correspond à tout, gourmand.
DavisDude
la source
1

C, 194 octets

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

Appeler avec:

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

SAS, 108

L'une des réponses les moins compétitives ici en raison de la syntaxe verbeuse de SAS - la pénalité de 9 caractères par expression régulière fait vraiment mal - mais c'était un bon exercice d'apprentissage de l'expression rationnelle:

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

Pyth, 35 octets

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

Explication

    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

la source
1

Perl 6, 75

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

GNU Sed, 65 octets

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

Une série de substitutions d'expression régulière. Utilise non portable \Lde GNU sed pour mettre en minuscule l'entrée. Exécutez à partir d'un fichier à l'aide de sed -f.

Jake Cobb
la source