one htaccess dev amigables java regex seo url-rewriting slug

htaccess - Código/biblioteca Java para generar babosas(para usar en URL bonitas)



url amigables php (5)

Los frameworks web como Rails y Django tienen soporte incorporado para "slugs" que se utilizan para generar URL legibles y amigables con el SEO:

Una cadena slug típicamente contiene solo los caracteres az , 0-9 y - y por lo tanto puede escribirse sin escape de URL (piense en "foo% 20bar").

Estoy buscando una función Java slug que, dada cualquier cadena Unicode válida, devuelva una representación de slug ( az , 0-9 y - ).

Una función de babosa trivial sería algo así como:

return input.toLowerCase().replaceAll("[^a-z0-9-]", "");

Sin embargo, esta implementación no manejaría la internacionalización y los acentos ( ë > e ). Una forma de evitar esto sería enumerar todos los casos especiales, pero eso no sería muy elegante. Estoy buscando algo más bien pensado y general.

Mi pregunta:

  • ¿Cuál es la forma más general / práctica de generar babosas tipo Django / Rails en Java?

He extendido la respuesta por @McDowell para incluir la escapatoria de la puntuación como guiones y para eliminar los guiones duplicados y los guiones anteriores y posteriores.

private static final Pattern NONLATIN = Pattern.compile("[^//w_-]"); private static final Pattern SEPARATORS = Pattern.compile("[//s//p{Punct}&&[^-]]"); public static String makeSlug(String input) { String noseparators = SEPARATORS.matcher(input).replaceAll("-"); String normalized = Normalizer.normalize(noseparators, Form.NFD); String slug = NONLATIN.matcher(normalized).replaceAll(""); return slug.toLowerCase(Locale.ENGLISH).replaceAll("-{2,}","-").replaceAll("^-|-$",""); }


La proposición de McDowel casi funciona, pero en casos como este Hello World !! devuelve hello-world-- (tenga en cuenta el -- al final de la cadena) en lugar de hello-world .

Una versión fija podría ser:

private static final Pattern NONLATIN = Pattern.compile("[^//w-]"); private static final Pattern WHITESPACE = Pattern.compile("[//s]"); private static final Pattern EDGESDHASHES = Pattern.compile("(^-|-$)"); public static String toSlug(String input) { String nowhitespace = WHITESPACE.matcher(input).replaceAll("-"); String normalized = Normalizer.normalize(nowhitespace, Normalizer.Form.NFD); String slug = NONLATIN.matcher(normalized).replaceAll(""); slug = EDGESDHASHES.matcher(slug).replaceAll(""); return slug.toLowerCase(Locale.ENGLISH); }




Normalize tu cadena usando la descomposición canónica:

private static final Pattern NONLATIN = Pattern.compile("[^//w-]"); private static final Pattern WHITESPACE = Pattern.compile("[//s]"); public static String toSlug(String input) { String nowhitespace = WHITESPACE.matcher(input).replaceAll("-"); String normalized = Normalizer.normalize(nowhitespace, Form.NFD); String slug = NONLATIN.matcher(normalized).replaceAll(""); return slug.toLowerCase(Locale.ENGLISH); }

Sin embargo, este es un proceso bastante ingenuo. No va a hacer nada para s-sharp (ß - utilizado en alemán), o cualquier alfabeto no latino (griego, cirílico, CJK, etc.).

Tenga cuidado al cambiar la caja de una cuerda. Las formas mayúsculas y minúsculas dependen de los alfabetos. En turco, la mayúscula de U + 0069 ( i ) es U + 0130 ( İ ), no U + 0049 ( I ), por lo que corre el riesgo de introducir un carácter que no sea latin1 en la cadena si utiliza String.toLowerCase() en un Localidad turca