Java-код/библиотека для создания пули (для использования в симпатичных URL-адресах)
Веб-фреймворки, такие как Rails и Django, имеют встроенную поддержку "slugs", которые используются для создания читаемых и SEO-дружественных URL-адресов:
Строка slug обычно содержит только символы a-z
, 0-9
и -
и поэтому может быть написана без экранирования URL (подумайте "foo %20bar" ).
Я ищу функцию Java slug, которая с учетом любой допустимой строки Unicode вернет представление slug (a-z
, 0-9
и -
).
Тривиальной функцией slug будет что-то вроде строк:
return input.toLowerCase().replaceAll("[^a-z0-9-]", "");
Однако эта реализация не будет обрабатывать интернационализацию и акценты (ë
> e
). Одним из способов этого было бы перечисление всех особых случаев, но это было бы не очень элегантно. Я ищу что-то более продуманное и общее.
Мой вопрос:
- Каков наиболее общий/практичный способ создания пулов Django/Rails в Java?
Ответы
Ответ 1
Нормализовать вашу строку, используя каноническое разложение:
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);
}
Это все еще довольно наивный процесс. Он не собирается ничего делать для s-sharp (& # xDF; - используется на немецком языке) или любого нелатинского алфавита (греческий, кириллический, CJK и т.д.).
Be careful when changing the case of a string. Upper and lower case forms are dependent on alphabets. In Turkish, the capitalization of U+0069 (i) is U+0130 (İ), not U+0049 (I) so you risk introducing a non-latin1 character back into your string if you use String.toLowerCase()
under a Turkish locale.
Ответ 2
http://search.maven.org/#search|ga|1|slugify
И здесь репозиторий GitHub взглянет на код и его использование:
https://github.com/slugify/slugify
Ответ 3
для других языков: http://www.codecodex.com/wiki/Generate_a_url_slug
Ответ 4
Я расширил ответ @McDowell, чтобы включить экранирование препинания в виде дефиса и удалить повторяющиеся и ведущие/конечные дефисы.
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("^-|-$","");
}
Ответ 5
Предложение McDowel почти работает, но в таких случаях, как этот Hello World !!
, он возвращает hello-world--
(обратите внимание на --
в конце строки) вместо hello-world
.
Фиксированная версия может быть:
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(text).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);
}