web-dev-qa-db-ja.com

わかりやすいURLを作成するときに無効な文字を削除するにはどうすればよいですか(つまり、スラッグをどのように作成しますか)。

このウェブページがあるとします:http://ww.xyz.com/Product.aspx?CategoryId=1

CategoryId = 1の名前が「犬」の場合、URLを次のようなものに変換したいと思います:http://ww.xyz.com/Products/Dogs

問題は、カテゴリ名に外部(またはURLに対して無効)文字が含まれている場合です。 CategoryId = 2の名前が「Göraäldre」の場合、新しいURLはどうなりますか?

論理的には、http://ww.xyz.com/Products/Göra äldreである必要がありますが、機能しません。

まず、スペース(たとえばダッシュで簡単に置き換えることができます)が原因ですが、外国の文字はどうですか? Asp.netでは、http://ww.xyz.com/Products/G%c3%b6ra+%c3%a4ldreのようなURLEncode関数を使用できますが、元のURL(http://ww.xyz.com/Product.aspx?CategoryId=2)よりも優れているとは言えません。

理想的には、これを生成したいのですが、どうすれば自動的にこれを実行できますか(つまり、外部文字を「安全な」URL文字に変換する):http://ww.xyz.com/Products/Gora-aldre

6
Anthony

次の2つの拡張メソッド(asp.net/C#)を思いつきました。

public static string RemoveAccent(this string txt)
{
    byte[] bytes = System.Text.Encoding.GetEncoding("Cyrillic").GetBytes(txt);
    return System.Text.Encoding.ASCII.GetString(bytes);
}

public static string Slugify(this string phrase)
{
    string str = phrase.RemoveAccent().ToLower();
    str = System.Text.RegularExpressions.Regex.Replace(str, @"[^a-z0-9\s-]", ""); // Remove all non valid chars          
    str = System.Text.RegularExpressions.Regex.Replace(str, @"\s+", " ").Trim(); // convert multiple spaces into one space  
    str = System.Text.RegularExpressions.Regex.Replace(str, @"\s", "-"); // //Replace spaces by dashes
    return str;
}
3
Anthony

それは、使用している言語と使用するテクニックによって異なります。 DjangoソースからのJavaScriptのこのスニペットを見てください。まさに必要なことを行います。あなたが選択した言語に簡単に移植できると思います。

これはPython slugify関数で使用されるDjangoスニペットで、はるかに短いです:

def slugify(value):
    """
    Normalizes string, converts to lowercase, removes non-alpha characters,
    and converts spaces to hyphens.
    """
    import unicodedata
    value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore')
    value = unicode(re.sub('[^\w\s-]', '', value).strip().lower())
    return re.sub('[-\s]+', '-', value)

共通の問題であるため、すべての言語にこの移植版があると思います。 slugify +あなたの言語のためだけに。

2
D4V360

各製品のURLセーフで一意の名前を含む新しいフィールドを製品テーブルに追加できます。これはおそらく最初に自動的に生成され(安全ではない文字を最も安全な同等の文字で置き換える-gora-aldre?)、その後必要に応じて微調整されます。

安全でない文字の置換は(常に)リバーシブルではないため、この種の処理をその場で実行することは完全に実行可能ではありません。

または、次のようにURLを作成します。

http://example.com/products/1234/safe-string

safe-stringはオンザフライで作成され、必要に応じて安全でない文字を置き換えます。番号1234はプロダクトキーです。キーを使用して製品を検索すると、ユーザーと検索エンジンにとって「安全な文字列」がより多くなります。

1
Kris

留意すべき2つのこと:

  1. 通常、URL書き換えは検索エンジンにプラスの効果をもたらしません(多くの場合マイナスの効果もあります)。ユーザーの満足度に測定可能なプラスの効果があることがわかっている場合にのみ実行してください(したがって、ユーザーに役立つURLを作成します) 。

  2. URLの書き換えを行うことにした場合、must技術的な詳細を完全に把握する必要があります。たとえば、同じコンテンツを表示する一意のURLを複数持つことはできません。非ASCIIコンテンツのエンコードにはUTF-8を使用し、コンテンツ内でエスケープリンクを使用し、通常はさまざまなブラウザーでテストして、計画どおりに動作することを確認します。これのどれかがあなたにとって異質なものであるなら、私は今のところURLの書き換えをしないことを強くお勧めします。

FWIW検索エンジン側の問題の一部は http://googlewebmastercentral.blogspot.com/2008/09/dynamic-urls-vs-static-urls.html でカバーされています

1
John Mueller

IMOの最良の方法は、無効な文字を探すのではなく、ホワイトリスト文字にすることです。ただし、éのようなアクセント記号付きの文字はかなり一般的であるため(これらがないとURLは奇妙になります)、これらを最初に変換できます。

PHPではstrtr関数を使用できますが、asp.netのニーズに合わせてこれを変更できるはずです。

strtr(
  'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûýýþÿŔŕ',
  'aaaaaaaceeeeiiiidnoooooouuuuybsaaaaaaaceeeeiiiidnoooooouuuyybyrr'
);

これがあなたのプロセスです:

  1. [オプション]文字列を小文字に変換します(通常はURLに推奨されます)。
  2. [オプション]上記のマッピングを使用してアクセント付き文字を変換します。
  3. 入力文字列を1文字ずつ実行します。
  4. 組み込み関数の種類によっては、文字列全体ではなく文字ごとに#1と#2を実行する方が高速な場合があります。
  5. 文字がa-zまたは-9の範囲にある場合、新しい文字列に追加します。それ以外の場合:
    a)新しい文字列の末尾に既にハイフンが付いている場合は、無視します
    b)そうでない場合は、文字列の末尾にハイフンを追加します。
  6. 最後に到達したら、ハイフンを先頭または末尾から削除して完了です!
1
DisgruntledGoat

投稿にはASP.Net: このサイトを見る というタグが付けられているため、(ほとんどの)テキストを発音区別記号(無効な文字と呼ぶ)を基本文字に置き換えるサンプルコードが含まれています。

Krisが述べたように、このサイトのように、URLで一意のIDを使用します。提供されたIDを制御できない場合は、外部の一意のIDを使用して、一意のIDを含む変換テーブルを作成する必要があります。そうすれば、外部IDが変更されたときにも内部参照が適切になります。一意のIDとともに、「検索および人間用に最適化されたID」を保存します。これはそれほど一意ではありませんが、見栄えがよくなります。

0
GvS

ウィキペディアでは、URLで非ラテン1文字がよく使用されます。これらのURLを使用しない理由(Webサーバーがそれらをサポートしていないこと以外)はありません。

しかしながら;これらの文字を避ける必要がある場合、それらをnon - diacritic 形式に置き換えることがわかりました。これらを読むほとんどの人は、発音区別符が削除されたとしても、Wordがどのようなものであるかを(コンテキストから)知ることができます。

0
Greg B