RailsやDjangoなどのWebフレームワークには、読み取り可能でSEOに適したURLを生成するために使用される「スラッグ」のサポートが組み込まれています。
スラッグ文字列には通常、文字a-z
、0-9
、および-
のみが含まれるため、URLをエスケープせずに書き込むことができます(「foo%20bar」と考えてください)。
有効なUnicode文字列を指定するとスラッグ表現(a-z
、0-9
、および-
)を返すJavaスラッグ関数を探しています。
些細なスラッグ関数は、次のようなものになります。
return input.toLowerCase().replaceAll("[^a-z0-9-]", "");
ただし、この実装は国際化とアクセントを処理しません(ë
> e
)。これを回避する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(ß-ドイツ語で使用)、または非ラテン語ベースのアルファベット(ギリシャ語、キリル文字、CJKなど)には何もしません。
文字列の大文字と小文字を変更するときは注意してください。大文字と小文字の形式はアルファベットに依存しています。トルコ語では、U + 0069(i)の大文字はU + 0130(İ)、U + 0049ではない([〜#〜] i [〜#〜])ので、latin1以外の文字を導入するリスクがありますトルコ語のロケールでString.toLowerCase()
を使用する場合は、文字列に戻ります。
http://search.maven.org/#search|ga|1|slugify
コードとその使用法を確認するためのGitHubリポジトリは次のとおりです。
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(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);
}
他の言語のリファレンスライブラリ: http://www.codecodex.com/wiki/Generate_a_url_slug
@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("^-|-$","");
}