¿Qué personaje es esa entidad HTML?

11

El objetivo es realmente simple. Al recibir una cadena como entrada, analice todas las entidades HTML que corresponden a los siguientes caracteres (incluidas sus variantes en mayúsculas):

áàãâäéèêëíìîïóòõôöúùûüýÿ

Reglas de análisis:

  • Cada entidad comienza con &y termina con;
  • El primer carácter después del &será el carácter modificado (¡la mayúscula es importante!)
  • Los caracteres restantes se refieren al nombre del acento utilizar ( acute, grave, circ, tildey uml). ¡El nombre de acento DEBE estar en minúsculas! * *
  • Cualquier entidad HTML que produce un carácter que no está en esa lista, o que no es válido, se debe dejar intacto (Ej: &, &etilde;, &a;)
  • Las entidades numéricas deben ignorarse, ya que no se ajustan a las reglas anteriores.

Este cambio se introdujo a partir del 18-02-2016. Todas las respuestas existentes que aceptan entidades HTML con mayúsculas son válidas. Cualquier respuesta futura debe seguir esta regla.

Ejemplos:

á //á
Téhèh //Téhèh
an & //an &

Salida:

La salida puede estar en ISO-8859- X (1-15), windows-1252 o UTF-8/16/32.
Puede elegir una y solo una de las codificaciones válidas y usarla para cualquier salida. Puede asumir con seguridad que la entrada estará en ASCII.

Cualquiera de los siguientes es un resultado válido para á:

  • á(ISO-8859-1 / 15 o windows-1252, equivalente a \xE1)
  • á(UTF-8, equivalente \xC3\xA1o \u00E1)
  • (UTF-8, equivalente a\xCC\x81o a\u0301)
  • Cualquier combinación de diacríticos, sin usar entidades HTML.

La salida debe ser visualmente similar, cuando se representa / muestra, a los caracteres de la lista.


Recuerde, todas las lagunas estándar e integradas * no están permitidas . Como se trata de , gana la respuesta más corta.

* Este cambio se realizó debido a la gran desaprobación de las bonificaciones y sanciones, y al momento de escribir, no invalida ninguna respuesta

Ismael Miguel
fuente
44
No voté, pero supongo que los votos negativos se deben a que a la gente realmente no le gustan los bonos / sanciones: terminan convirtiendo un desafío en varios mini desafíos.
Kevin W.
1
@KevinW. Como expliqué en el sandbox, solo dejé esas penalidades porque quiero ver qué cosas geniales incorporadas pueden inventar las personas. Pero obviamente, no quiero estropear la diversión de todos. Si no pongo la penalidad, una respuesta como el ejemplo de Javascript que di, sería suficiente. Y eso no requería trabajo en absoluto.
Ismael Miguel
1
En mi humilde opinión, las bonificaciones parecen arbitrarias, ya sea permitir o no permitir, no interfieras.
Addison Crump
1
@IsmaelMiguel Sugiero que no haya bonificaciones / penalizaciones: permita los métodos de programación que deseen utilizar (fuera de las lagunas estándar, por supuesto) y elimine las bonificaciones / penalizaciones.
Addison Crump
2
@IsmaelMiguel Nah: esos fueron todos mis centavos. c:
Addison Crump

Respuestas:

4

Japt, 81 75 bytes

Ur`&([%vYy](ac©e|uml)|%v(g?ve|circ)|[AaOo]Èìe);`@Yg +'Ì+"?????"g"gutca"bYgJ

Los seis ?s representan caracteres no imprimibles. ¡Pruébalo en línea!

Nota: Esto genera la tercera opción de codificación; es decir, la letra seguida de la codificación UTF-8 sin procesar de la marca diacrítica combinada correspondiente.

Cómo funciona

Ur"&(    );"       // Replace each ampersand and semicolon that have one of these between them:
([%vYy](acute|uml) //  A vowel or Yy followed by "acute" or "uml",
|%v(grave|circ)    //  or a vowel followed by "grave" or "circ",
|[AaOo]tilde       //  or "a" or "o" followed by "tilde";
@                  // replace each match X and its middle Y with this function:
""g"gutca"bYgJ     //  Take the unprintable at index (index of the second char in Y in "gutca") in this string.
Yg +'Ì+            //  Concatenate the first char in Y and "Ì" to the beginning.
                   // Implicit output

Hexdump del código:

00000000: 55 72 60 26 28 5b 25 76 59 79 5d 28 61 63 a9 65  Ur`&([%vYy](ac©e
00000010: 7c 75 6d 6c 29 7c 25 76 28 67 9f 76 65 7c 63 69  |uml)|%v(g.ve|ci
00000020: 72 63 29 7c 5b 41 61 4f 6f 5d c8 ec 65 29 3b 60  rc)|[AaOo]Èìe);`
00000030: 40 59 67 20 2b 27 cc 2b 22 80 81 82 83 88 22 67  @Yg +'Ì+"....."g
00000040: 22 67 75 74 63 61 22 62 59 67 4a                 "gutca"bYgJ
ETHproductions
fuente
Parece funcionar bien. ¿Puedes por favor proporcionar un hexdump? Parece que tiene algunos caracteres "extraños" que pueden no funcionar en cada codificación.
Ismael Miguel
@IsmaelMiguel Me acabo de dar cuenta de que los acentos no son parte de la codificación ISO-8859-1; Por lo tanto, descomprimí la cadena y cambié a bytes UTF-8. ¿Todavía te gustaría un hexdump?
ETHproductions
Depende de usted, pero su solución anterior estaba perfectamente bien.
Ismael Miguel
Creo que podría tener un pequeño insecto allí, su código parece dejar Ýsolo, pero debe ser cambiado a Y ...
daavko
@daavko ¡Vaya, tienes razón! Corregido ahora.
ETHproductions
12

JavaScript (ES6), 141 122 134 bytes

a=>a.replace(/&([aeiouyAEIOUY](acute|uml)|[aeiouAEIOU](grave|circ)|[aoAO]tilde);/g,b=>b[1]+{g:"̀",a:"́",c:"̂",t:"̃",u:"̈"}[b[2]])

Seguí el ejemplo de daavko usando signos diacríticos, y me siento como un idiota por no pensar en usarlo antes. En realidad se vuelve sorprendentemente corto para JavaScript.

EDITAR: Neil captó algunos casos graves de indefinido, que ahora se corrigen.

Mwr247
fuente
¿Ver? ¡Te dije que podrías cortar algo de grasa! ¡Esta es una respuesta realmente sorprendente! Realmente espero que obtengas más +1's
Ismael Miguel
1
Esto es simplemente inteligente. +1
Yytsi
Me encanta..! String.prototype.replacees tan ridículamente golfable para el cruce de cuerdas.
Archenoth
No estoy convencido de que esto haga lo correcto para É(lo que sea que sea lo correcto).
Neil
Lamentablemente, @Neil tiene razón. Las entidades HTML en mayúsculas son consideradas inválidas por los navegadores. Pero no especifiqué que el nombre del acento debería estar en minúsculas. Eso es completamente mi culpa. Consideraré esta respuesta válida y todas las que ya fueron publicadas. Pero cualquier nueva respuesta debe tener los nombres de acento en minúsculas.
Ismael Miguel
10

Retina , 115 bytes

Soy nuevo en code-golf, pero creo que esto podría funcionar.
Esta versión se realizó antes de que se introdujera la regla, que no permite reemplazar entidades html en mayúsculas (por ejemplo Á).

i`&([aeiouy])acute;
$1́
i`&([aeiou])grave;
$1̀
i`&([ao])tilde;
$1̃
i`&([aeiou])circ;
$1̂
i`&([aeiouy])uml;
$1̈

Bastante simple búsqueda y reemplazo. Utiliza UTF-8.

Utiliza el enfoque [letra] \ xCC \ x [código hexadecimal de marca diacrítica]. La marca diacrítica se agrega después de cada letra relevante.

Por alguna razón, la fuente Droid Sans Mono predeterminada en el intérprete no puede representar las letras "circ" y "uml" correctamente. Si lo cambia a través de herramientas de desarrollador a algo como DejaVu Sans, se muestra muy bien. Creo que esto es una limitación de la fuente, no del programa. Pero si es culpa del programa, intentaré solucionarlo.

Aquí hay una versión de 129 bytes, que no reemplaza las entradas HTML en mayúsculas (por ejemplo Á)

&([aeiouyAEIOUY])acute;
$1́
&([aeiouAEIOU])grave;
$1̀
&([aoAO])tilde;
$1̃
&([aeiouAEIOU])circ;
$1̂
&([aeiouyAEIOUY])uml;
$1̈

Pruébalo en línea!
Pruébalo en línea! Versión de 129 bytes

daavko
fuente
Gran uso de las marcas allí. No puedo creer que no pensara en que fuera más corto al principio> _ <
Mwr247
@ Mwr247 ¡Gracias! Estaba buscando una manera de hacer esto, ya que quería intentar hacerlo y las marcas aparecieron en alguna parte ... Estoy sinceramente sorprendido de que sea tan corto.
daavko
1
¡Buen juego limpio y uso de las reglas! Nunca me gustó este idioma, pero realmente me encanta esta respuesta. Instantáneo +1
Ismael Miguel
Conté 115 bytes (110 caracteres + 5 bytes adicionales para las marcas).
Mwr247
@ Mwr247 Oh, tienes razón. Simplemente lo pegué en un documento de texto y ejecuté ls -l y mostró 116 ... parece que el editor agregó una nueva línea adicional al final. Lo arreglaré.
daavko
3

JavaScript (ES6), 288 bytes

a=>(z=(b,c=1,d=2,e=3,f=0,g=4)=>({b:b+191,grave:c,acute:d,circ:e,tilde:f,uml:g}),y={a:z(0,1,2,3,4,5),e:z(8),i:z(12),o:z(18,1,2,3,4,5),u:z(25),y:z(28,0,2,0)},a.replace(/&\w+;/gi,b=>(x=y[b[1].toLowerCase()])&&(w=x[b.slice(2,-1)])?String.fromCharCode(x.b+w+32*(b[1]>'_')+153*/Yu/.test(b)):b))

Crea un objeto de mapa de caracteres (con el código numérico de base para cada carácter) y usa compensaciones (o 0 si no existen) para determinar si una entidad debe convertirse y cuál es su código de caracteres. La simetría en los casos significa agregar 32 si es minúscula, excepto para &Yuml;, donde usa un desplazamiento diferente para UTF8.

Mwr247
fuente
¡Agradable! Realmente me gusta su enfoque, pero 286 bytes es un poco largo. ¿Quizás hay algunas cosas que se pueden cortar? Recortar un poco de grasa sería genial
Ismael Miguel
@IsmaelMiguel 288 en realidad; Me acabo de dar cuenta de que de hecho hay un &Yuml;UTF8: está en un lugar extraño. De todos modos, pensé que lo condensé y lo optimicé bastante bien, considerando que una lista de reemplazo literal sería más del doble. ¿Estás viendo algo que yo no soy?
Mwr247
En realidad no ... Debe haber una mejor manera de hacer letras minúsculas que usando .toLowerCase(). Ese nombre es ENORME !!! Además, String.fromCharCodepuede aceptar múltiples parámetros, o ser llamado comoString.fromCharCode.call([...])
Ismael Miguel
1
@IsmaelMiguel Parece que tenía razón acerca de que necesitaba una reescritura, pero estaba equivocado acerca de que necesitaba ser otra persona. Creo que esta respuesta es más interesante, pero la otra es técnicamente más concisa, por lo que las he incluido por separado.
Mwr247
1
No cambia la vida, pero su expresión regular no contiene letras literales, por lo que no necesita la ibandera.
Neil