code Java / bibliothèque pour générer des limaces (pour une utilisation dans les URL jolies)
-
11-09-2019 - |
Question
frameworks Web tels que Rails et Django a un support intégré pour les « limaces » qui sont utilisés pour générer des URL lisibles et SEO friendly:
Une chaîne de limaces contient généralement que des caractères a-z
, 0-9
et -
et peut donc être écrit sans-escaping URL (pensez "foo% 20bar").
Je suis à la recherche d'une fonction de limace Java qui donne une chaîne Unicode valide retourne une représentation de limace (a-z
, 0-9
et -
).
Une fonction de limace trivial serait quelque chose le long des lignes de:
return input.toLowerCase().replaceAll("[^a-z0-9-]", "");
Cependant, cette mise en œuvre ne traiterait pas l'internationalisation et des accents (ë
> e
). Une façon de contourner ce serait d'énumérer tous les cas particuliers, mais ce ne serait pas très élégant. Je cherche quelque chose de plus bien pensé et général.
Ma question:
- Quelle est la manière la plus générale / pratique pour générer des limaces de type Django / Rails en Java?
La solution
Normaliser votre chaîne en utilisant la décomposition canonique:
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);
}
Ceci est encore un processus assez naïf, cependant. Il ne va rien faire pour s-forte (ß - utilisé en allemand)., Ou tout alphabet à base de caractères non latins (grec, cyrillique, CJC, etc)
Soyez prudent lorsque vous modifiez le cas d'une chaîne. formes minuscules et majuscules dépendent alphabets. En Turquie, la capitalisation de U + 0069 ( i ) est U + 0130 ( I ) et U + 0049 ( I ) et vous risque d'introduire un caractère non-latin1 de nouveau dans votre chaîne si vous utilisez String.toLowerCase()
une locale turque.
Autres conseils
http://search.maven.org/#search|ga|1|slugify
Et voici le dépôt GitHub pour jeter un oeil sur le code et son utilisation:
J'ai étendu la réponse par @McDowell pour inclure échapper à la ponctuation comme des traits d'union et de supprimer les doublons et de premier plan / arrière des traits d'union.
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 proposition de McDowel fonctionne presque, mais dans des cas comme celui-ci Hello World !!
retourne hello-world--
(notez le --
à la fin de la chaîne) au lieu de hello-world
.
Une version fixe pourrait être:
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);
}
Bibliothèque de référence, pour les autres langues: http://www.codecodex.com/wiki/Generate_a_url_slug