web-dev-qa-db-ja.com

Javaスラッグを生成するためのコード/ライブラリ(きれいなURLで使用するため)

RailsやDjangoなどのWebフレームワークには、読み取り可能でSEOに適したURLを生成するために使用される「スラッグ」のサポートが組み込まれています。

スラッグ文字列には通常、文字a-z0-9、および-のみが含まれるため、URLをエスケープせずに書き込むことができます(「foo%20bar」と考えてください)。

有効なUnicode文字列を指定するとスラッグ表現(a-z0-9、および-)を返すJavaスラッグ関数を探しています。

些細なスラッグ関数は、次のようなものになります。

return input.toLowerCase().replaceAll("[^a-z0-9-]", "");

ただし、この実装は国際化とアクセントを処理しません(ë> e)。これを回避する1つの方法は、すべての特殊なケースを列挙することですが、それはあまりエレガントではありません。もっとよく考えられた一般的なものを探しています。

私の質問:

  • JavaでDjango/Railsタイプのスラッグを生成するための最も一般的/実用的な方法は何ですか?
37
knorv

正規化 正規分解を使用した文字列:

_  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()を使用する場合は、文字列に戻ります。

40
McDowell

http://search.maven.org/#search|ga|1|slugify

コードとその使用法を確認するためのGitHubリポジトリは次のとおりです。

https://github.com/slugify/slugify

13
dtrunk

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);
}
5
Mariano Ruiz

他の言語のリファレンスライブラリ: http://www.codecodex.com/wiki/Generate_a_url_slug

2
Rafael Sanches

@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("^-|-$","");
  }
2
Mike Godin