Rails和Django等Web框架内置了对“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
)。解决这个问题的一种方法是列举所有特殊情况,但这不是很优雅。我正在寻找更好的思考和一般性的东西。
我的问题:
答案 0 :(得分:37)
Normalize你的字符串:
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(ß - 德语中使用)或任何非拉丁语字母(希腊语,西里尔语,CJK等)做任何事情。
更改字符串的大小写时要小心。大写和小写形式取决于字母表。在土耳其语中,U + 0069( i )的大写是U + 0130( ),而不是U + 0049(我)所以你如果您在土耳其语区域设置下使用String.toLowerCase()
,则可能会在您的字符串中引入非latin1字符。
答案 1 :(得分:12)
http://search.maven.org/#search|ga|1|slugify
这是GitHub存储库,用于查看代码及其用法:
答案 2 :(得分:2)
我已经扩展了@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("^-|-$","");
}
答案 3 :(得分:2)
麦克道尔的命题几乎可行,但在这种情况下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(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);
}
答案 4 :(得分:1)
参考图书馆,适用于其他语言:http://www.codecodex.com/wiki/Generate_a_url_slug