Code Java/bibliothèque pour générer des slugs (à utiliser dans les belles URLs))
cadres Web tels que les Rails et Django a intégré le soutien pour "slugs" qui sont utilisés pour générer lisible et SEO-friendly URLs:
- limaces dans les Rails
- limaces à Django
une chaîne de slug contient typiquement seulement des caractères a-z
, 0-9
et -
et peut donc être écrite sans url-escapade (pensez à "foo%20bar").
je cherche une fonction Java slug qui, avec une chaîne Unicode valide, renvoie une représentation slug ( a-z
, 0-9
et -
).
une fonction triviale de limace serait quelque chose dans le genre de:
return input.toLowerCase().replaceAll("[^a-z0-9-]", "");
cependant, cette mise en œuvre ne traiterait pas l'internationalisation et les accents ( ë
> e
). Un moyen d'éviter cela serait d'énumérer tous les cas particuliers, mais ce ne serait pas très élégant. Je cherche quelque chose de plus réfléchi et général.
ma question:
- Quelle est la manière la plus générale/pratique de générer des balles de type Django/Rails en Java?
5 réponses
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-sharp (ß-utilisé en allemand), ou tout autre alphabet non-Latin (grec, cyrillique, CJK, etc).
soyez prudent lorsque vous changez le cas d'une chaîne. Les formes en majuscules et en minuscules dépendent de l'alphabet. En Turc, la capitalisation de U+0069 ( i ) est U+0130 ( i ), pas U+0049 ( i ) donc vous risquez d'introduire un caractère non-latin1 dans votre chaîne si vous utilisez String.toLowerCase()
sous une locale turque.
http://search.maven.org/#search/ga/1/slugify
et voici le dépôt GitHub pour jeter un coup d'oeil au code et à son usage:
bibliothèque de référence, pour les autres langues: http://www.codecodex.com/wiki/Generate_a_url_slug
j'ai étendu la réponse de @McDowell pour inclure le fait d'échapper la ponctuation en tant que traits d'Union et pour supprimer les traits d'Union dupliqués et menant/suivant.
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 !!
il retourne hello-world--
(notez le --
à la fin de la chaîne de caractères) 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);
}