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?
31
demandé sur Community 2009-11-01 16:40:00

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.

35
répondu McDowell 2009-11-01 14:38:07

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:

https://github.com/slugify/slugify

10
répondu dtrunk 2012-07-17 17:42:32

bibliothèque de référence, pour les autres langues: http://www.codecodex.com/wiki/Generate_a_url_slug

1
répondu Rafael Sanches 2012-07-02 00:08:46

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("^-|-$","");
  }
1
répondu Mike Godin 2015-11-20 16:21:11

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);
}
1
répondu Mariano Ruiz 2018-07-25 13:42:49