Títulos amigables con URL

28

Las personas en este sitio realmente adoran embellecer sus títulos de publicaciones ...

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

Sin embargo, cuando este título debe incluirse en la URL de la página, se simplifica:

stewies-sequence

El reto

Su tarea es crear un programa o función que, dada una cadena que representa el título de una publicación, genera / devuelve su conversión "URL-Friendly".

El algoritmo es:

  • Convertir a minúsculas (cuando corresponda)
  • Reemplace cada espacio ( ), punto ( .), coma ( ,) o barra diagonal ( /) con un guión ( -)
  • Elimine los caracteres no alfanuméricos, excepto los guiones.
  • Minifique grupos de guiones adyacentes ( a---b -> a-b), elimine los que están al principio / al final

Tenga en cuenta que este algoritmo es una simplificación y que no siempre produce los mismos resultados que el método real del sitio.


Reglas

  • Puede suponer esa entrada:
    • No estará vacío.
    • Contendrá al menos un carácter alfanumérico.
    • Solo contendrá caracteres en el rango ASCII 32-126 (imprimible)
  • Se permiten programas o funciones completos.
  • No se permite una construcción que haga la especificación exacta de la tarea .
  • Este es el , por lo que gana la solución más corta (en bytes).

Casos de prueba

La mayoría de las publicaciones en este sitio servirán como pruebas, pero aquí hay una lista útil:

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

Algunos más largos ...

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

Y algunas muestras de verificación de casos extremos (siéntase libre de sugerir más):

0123   ->   0123
a a1   ->   a-a1
2-1=1  ->   2-11
FlipTack
fuente
¿Qué pasa con los -s principales ? ¿Tendrán que ser removidos? Por ejemplo asdf-, ¿se -tendrá que eliminar el último ?
Kritixi Lithos
¿Podemos usar una función incorporada para verificar si el carácter es alfanumérico como esteif(isalphanum(ch))...
Mukul Kumar
1
@KritixiLithos Minifique grupos de guiones adyacentes (a --- b -> ab), elimine los que están al principio / al final. Supongo que esto debería aclararte.
Mukul Kumar
¿Y qué hay de los _guiones bajos? Mi código funciona excepto cuando hay guiones bajos.
Kritixi Lithos
@ L3viathan No importa ahora, cambié mi código para que incluso se eliminen los guiones bajos
Kritixi Lithos

Respuestas:

7

Retina, 33 31 bytes

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

\W+
-
^-|-$

(El programa tiene una nueva línea final)

No estoy seguro de poder sacar más provecho de esto. Esto debería cubrir todo. Vino similar a Mama Fun Roll's. Otra versión de 33 bytes que usa expresiones regulares recursivas

Pruébalo en línea!

Explicación

T`L`l

Esta línea es simple, se convierte a minúsculas mediante T ransliterating A-Z( L) a a-z( l, minúsculas).


Esta etapa es simple, esencialmente elimina todos los caracteres innecesarios para evitarnos muchos problemas más adelante.

[^a-z ,-9]+

[^a-z ,-9] Coincide con cualquier personaje que NO sea:

  • a-z: alfabeto en minúsculas (recuerde que la cadena completa está en minúsculas debido al elemento anterior)
  • : carácter espacial
  • ,-9este es el código de caracter gama de ,a 9que resulta ser ,-./0123456789, exactamente los caracteres que necesitamos

A continuación, convertimos todos los caracteres no alfanuméricos en guiones (que ahora es justo y ,./-.

\W+
-

Esto no coincidirá (no) lo _que se incluye en \w(negación de \W) porque se eliminó en la etapa anterior

Downgoat
fuente
Creo que esto fallará para entradas como a = b.
Martin Ender
Realmente quiero aceptar esto, pero como dijo Martin, no minimiza los guiones adyacentes cuando a = b
ingresas
@ Flp.Tkc perdón por la respuesta tardía (Semana de la final ahora mismo) Me las arreglé para exprimir dos bytes más y arreglarlo. Creo que esto maneja correctamente estos casos ahora
Downgoat
9

JavaScript (ES6), 90 82 79 75 bytes

Este es un intento de hacer el trabajo con una sola replace(). Este código extrae solo los caracteres que nos interesan e ignora todo lo demás. Hay alguna lógica adicional para procesar los guiones.

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

Casos de prueba

Arnauld
fuente
1
Para ,a^a,, este código da -aa-(hay guiones
iniciales
@KritixiLithos Oh, gracias por señalar esto. No presté atención a esa regla. Eso debería ser arreglado.
Arnauld
9

V , 41, 40, 37 , 36 bytes

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

Pruébalo en línea! o ¡ Verifique todos los casos de prueba a la vez!

Como de costumbre, aquí contiene un montón de caracteres no imprimibles y no ASCII, así que aquí hay 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                                -.-$

En estos desafíos, el sistema de "Regex comprimido" de V es útil.

Explicación

Primero lo primero, convertiremos todo a minúsculas. Afortunadamente, hay una forma realmente conveniente de hacer esto en dos bytes. Escribí un consejo sobre eso aquí . Entonces hacemos

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

Después de eso, hacemos un montón de comandos sustitutos comprimidos. Una buena descripción de cómo funciona la expresión regular comprimida de V puede ser confusa aquí , pero la idea básica es que podemos establecer el bit alto para evitar tener que escapar de ciertos caracteres. Otra conveniencia es que los rangos (me gusta :%) y las banderas (me gusta /g) se completan automáticamente. Pero al final, todo se traduce en comandos sustitutos vim. De hecho, incluso podríamos traducir directamente el resto del programa a vim. Eso nos daría esto:

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

Si hablas vim-regex, debería quedar más claro lo que hace el resto del programa ahora. Así que aquí está el resto del programa:

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

JavaScript (ES6) 91 96

1 bytes guardados thx @ETHproductions

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

Prueba

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
fuente
Esto tiene exactamente el mismo bytecount que mi respuesta si se convierte en una función con nombre
Kritixi Lithos
No creo que necesites lo último *en la última expresión regular, aunque puedo estar equivocado
ETHproductions
Puedo estar equivocado, pero ¿estás seguro de que la búsqueda anticipada es necesaria?
Kritixi Lithos
@KritixiLithos la búsqueda anticipada es necesaria para mantener al menos 1 - dentro de la cadena, mientras se elimina todo al inicio y al final
edc65
@ETHproductions bien, gracias
edc65
4

Python 3, 103 100 96 95 bytes

5 bytes guardados gracias a Flp.Tkc

import re
lambda s,y=re.sub,d='-':y('-+',d,y('[^0-9a-z-]','',y('[ .,/]',d,s.lower()))).strip(d)
L3viatán
fuente
@ Flp.Tkc Indeed ..
L3viathan
Vaya, accidentalmente rechacé esto. No puedo revertir mi voto hasta que edite esta publicación
Kritixi Lithos
@KritixiLithos Hecho
L3viathan
4

Retina, 34 bytes

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

\ W +
-
^ - | - $

Pruébalo en línea!

Tenga en cuenta la nueva línea final. Esencialmente, la implementación del OP.

Mama Fun Roll
fuente
El enlace TIO apunta a un código ligeramente diferente
Kritixi Lithos,
Sí, lo acabo de arreglar.
Mama Fun Roll
1
Puede usar T`L`lpara ir a minúsculas con menos bytes
Downgoat
Falla en algo a..similar
Downgoat
2
[\W]es solo\W
Martin Ender
3

MATL , 38 bytes

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

Pruébalo en línea! O verificar todos los casos de prueba .

Explicación

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

Ruby , 61 60 61 64 53 bytes

(52 bytes de código más un byte para el -p)

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

Pruébalo en línea!

tr()- convierte caracteres en mayúscula, espacio, coma, punto y barra diagonal. Sustituya temporalmente el -espacio en blanco para que pueda usarlo stripmás adelante.
Tenga -en cuenta que el carácter en la "A-Z ,-/"expresión es en realidad un operador de rango, que también hace que el .carácter esté sujeto a transformación. Esta maniobra en realidad no reducirá los bytes, pero es elegante, por lo que puede quedarse.

gsub(/[^\w ]/){} - eliminar todos los caracteres que no están en el conjunto permitido.

split- técnicamente, no necesitamos exactamente esa matriz, pero splitelimina los espacios en blanco iniciales y finales (que en realidad son -caracteres disfrazados). Como beneficio adicional, esto comprime juntas carreras de múltiples espacios.

*?-- Taquigrafía para .join("-"); Esto invierte tanto la splitoperación anterior como la transformación de espacios en blanco al mismo tiempo. Un byte más se guarda usando la notación abreviada para literales de caracteres , lo que hace que el programa requiera Ruby 1.9 o más reciente.

Actualización 1: Usar en getslugar del modo de edición de flujo de Ruby ahorra un byte.
Revertido según la sugerencia de ValueInk .

Actualización 2: (+3 bytes en general)

  • Caso de borde fijo ..--hi, $/(→ hi) (+10 bytes) : una vez más, cortesía del usuario ValueInk
  • Tomó malus por -p (+1 byte)
  • Eliminé squeezey usé en su gsublugar (+2 bytes) , lo que me permitió:
  • Utilícelo strippara manejar los guiones iniciales y finales (-10 bytes) .

Actualización 3: Hattrick por ValueInk. Ahorramos 11 bytes al aprovechar String#splitel hábito de apretar automáticamente las corridas del mismo separador, lo que nos permite deshacernos de la cadena strip/ final completa gsuby reemplazarla por un split/ joincombo. (-11 bytes)

Synoli
fuente
Esto solo devuelve la cadena en un entorno REPL y falla si se ejecuta como un programa Ruby adecuado, y eso no es bueno. Programas completos o funciones / solo lambdas. De hecho, su versión anterior habría funcionado con la -pbandera, pero esto definitivamente no lo hará.
Value Ink
@ValueInk Por supuesto, tienes razón. He cambiado mi solución en consecuencia. Gracias por tu comentario; es exactamente el tipo de orientación que aprecio mucho, ya que este es mi primer intento de jugar al golf.
Synoli
1
Gracias por hacer la corrección; He eliminado mi voto negativo. Una cosa a tener en cuenta es que el uso del -pindicador agrega implícitamente 1 byte a su código (porque cambia la ejecución de su código de ruby -e 'your code'a ruby -pe 'your code'). También he encontrado un caso de borde donde da -hi-información como ..--hi, $/cuando debería eliminar todos los guiones iniciales / finales y, por lo tanto, regresar hi.
Value Ink
2
-2 bytes cambiando gsub(/[^\w ]/){}a tr('^a-z ',''), y luego termina con en .split*?-lugar de .strip.gsub...ya que maneja automáticamente los duplicados y los extremos de la cadena, ¡todo de una vez!
Value Ink
1
Como nadie lo dijo, ¡bienvenido a code-golf!
FlipTack
3

JavaScript (ES6), 74 69 bytes

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>

Editar: ahorré 5 bytes al darme cuenta de que ya había eliminado todos los caracteres, excepto -/,. 0-9a-zque puedo usar \wpara unir las palabras restantes.

Neil
fuente
Creo que debe incluir el código HTML en el bytecount ya que se está utilizando para resolver el desafío
Kritixi Lithos
1
@KritixiLithos No, solo está allí para fines de demostración. La pregunta dice que mi código puede asumir al menos un carácter alfanumérico, y el código HTML simplemente prueba esto antes de llamar a la función.
Neil
[a-z\d]podría ser [^\W_]?
edc65
@ edc65 Bien, pero luego me di cuenta de que podría ser aún más simple.
Neil
2

PHP, 87 bytes

La idea de las expresiones regulares proviene de respuestas existentes.

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

Requiere que tenga un servidor que ejecute PHP y que acceda a través de HTTP.

El título debe estar en la tecla Ty el resultado se imprimirá en la pantalla.

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

Ismael Miguel
fuente
2

herramientas bash / Unix, 56 bytes

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

Reemplace las mayúsculas con minúsculas y los caracteres especiales requeridos con guiones.

Elimine (opción -d para tr) caracteres que no sean letras, dígitos y guiones, y luego exprima (opción -s para tr) guiones múltiples en una fila en un solo guión.

Eliminar guiones al principio, y luego al final.

Mitchell Spector
fuente
2

Powershell, 85 bytes

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

lo convierten en minúsculas, a continuación, 3 reemplaza expresiones regulares en una fila, y recortar cualquier arrastran -'s

colsw
fuente
podría no $inputahorrarte 2 bytes?
briantist
2

JavaScript, 90 98 94 93 91 90 91 bytes

¡1 byte guardado gracias a @ edc65!

¡1 byte guardado gracias a @IsmaelMiguel por detectar un punto y coma líder!

1 byte obtenido después de fallar ,a-^-a,

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

Lo que más me gusta de esta presentación en particular son los rangos. En la primera replace, se elimina todo lo que no es alfanumérico y no una ,, -, ., /y no un espacio. ¡Usamos a-zpara detectar las letras, y usamos ,-9para detectar esos caracteres y números especiales ya que los códigos de caracteres de estos literales ASCII se alinean!

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

Kritixi Lithos
fuente
No elimina los guiones iniciales: "-1" se convierte en "-1", cuando debería convertirse en "1".
L3viathan
@ L3viathan debería funcionar ahora
Kritixi Lithos
No es necesario contar, f=por lo que su recuento de bytes es 96 en este momento. Y no hay necesidad de \ dentro de un rango en la expresión regular, por lo que podría ser 95. Pero ... todavía no funciona: intente...title
edc65
1
Hei No soy ese viejo! (65 no 64)
edc65
1
Creo que no necesitas el f=y el ;al final. Solo especifique que esta es una función anónima. Con esto, su respuesta debe tener 90 bytes de longitud.
Ismael Miguel
1

Lua, 91 bytes

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

¿Dónde aestá la cadena de URL?

Explicación:

  • La mayor parte es bastante sencillo. a:lower()devuelve la función en minúsculas
  • :gsub encuentra la coincidencia del patrón y lo reemplaza con la cadena.
  • '[ .,/]': Los corchetes significan "o", por lo que esto coincide con el espacio, punto, coma y barra diagonal. No es necesario ser codicioso porque :gsubtodas las ocurrencias.
  • '[^%w-]': ^significa "no" cuando está entre paréntesis, %wsignifica cualquier cosa alfanumérica. Entonces '[^%w-]coincide con cualquier cosa que no sea alfanumérica o un guión.
  • '%-+': Combina tantos guiones como puedas y reemplázalos con un solo guión.
  • match'%-?(.*)%-?': En Lua, si una cadena es el único argumento de la función, no se necesitan paréntesis. Solo necesita verificar un guión al inicio y al final porque los guiones ya se han minimizado. No hay necesidad de personajes de anclaje porque .*es coincidir con todo, codicioso.
DavisDude
fuente
1

C, 194 bytes

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

Llamar con:

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

SAS, 108

Una de las respuestas menos competitivas aquí debido a la sintaxis detallada de SAS (la penalización de 9 caracteres por expresión regular realmente duele), pero fue un buen ejercicio de aprendizaje de expresiones regulares:

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

Pyth, 35 bytes

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

Explicación

    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

fuente
1

Perl 6, 75

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

GNU Sed, 65 bytes

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

Una serie de sustituciones de expresiones regulares. Utiliza no portátil \Lde GNU sed para poner en minúscula la entrada. Ejecutar desde un archivo usando sed -f.

Jake Cobb
fuente