Как удалить недопустимые символы при создании дружественного 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://www.xyz.com/Products/Göra äldre
но это не сработает. Во-первых, из-за пространства (которое я могу легко заменить тире, например), но как насчет иностранных символов? В Asp.net я мог бы использовать функцию URLEncode, которая даст что-то вроде этого:
http://ww.xyz.com/Products/G%c3%b6ra+%c3%a4ldre
но я не могу сказать это лучше, чем оригинальный url (http://ww.xyz.com/Product.aspx?CategoryId=2)

В идеале я хотел бы сгенерировать этот, но как я могу это сделать автоматически (т.е. преобразование иностранных символов в "безопасные" URL-адреса):
http://ww.xyz.com/Products/Gora-aldre

Ответ 1

Я придумал два следующих метода расширения (asp.net/С#):

     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;
    }

Ответ 2

Транслитерайте символы без ASCII в ASCII, используя что-то вроде этого:

var str = "éåäöíØ";
var noApostrophes = Encoding.ASCII.GetString(Encoding.GetEncoding("Cyrillic").GetBytes(str)); 

=> "eaaoiO"

(Источник)

Ответ 3

Еще одна вещь, которую стоит рассмотреть:

Если пользователь предоставляет строку, такую ​​как 好听的音乐, которую вы хотите преобразовать в URL-адрес, совместимый с URL, вам следует рассмотреть возможность использования IdnMapping

Например:

string urlFriendlyTitle = Slugify(url);

public static string Slugify(string text)
{
    IdnMapping idnMapping = new IdnMapping();
    text = idnMapping.GetAscii(text);

    text = RemoveAccent(text).ToLower();

    //  Remove all invalid characters.  
    text = Regex.Replace(text, @"[^a-z0-9\s-]", "");

    //  Convert multiple spaces into one space
    text = Regex.Replace(text, @"\s+", " ").Trim();

    //  Replace spaces by underscores.
    text = Regex.Replace(text, @"\s", "_");

    return text;
}

public static string RemoveAccent(string text)
{
    byte[] bytes = Encoding.GetEncoding("Cyrillic").GetBytes(text);

    return Encoding.ASCII.GetString(bytes);
}

Без этого 好听的音乐 будет преобразован в string.Empty. При этом xn--fjqr6lw2ek78az68a, который punycode

Ответ 4

Я использую функцию, описанную в http://www.blackbeltcoder.com/Articles/strings/converting-text-to-a-url-friendly-slug. Он не поддерживает напрямую неанглийские символы, но может быть легко обновлен для поддержки дополнительных символов.

Мне это нравится, потому что он создает очень чистый вид.