Вот мое представление, основанное на ответах Джоан и Марселя. Я сделал следующие изменения:
- Используйте широко распространенный метод для удаления акцентов.
- Явное кэширование Regex для скромных улучшений скорости.
- Больше разделителей слов, распознанных и нормализованных к дефисам.
Вот код:
public class UrlSlugger
{
// white space, em-dash, en-dash, underscore
static readonly Regex WordDelimiters = new Regex(@"[\s—–_]", RegexOptions.Compiled);
// characters that are not valid
static readonly Regex InvalidChars = new Regex(@"[^a-z0-9\-]", RegexOptions.Compiled);
// multiple hyphens
static readonly Regex MultipleHyphens = new Regex(@"-{2,}", RegexOptions.Compiled);
public static string ToUrlSlug(string value)
{
// convert to lower case
value = value.ToLowerInvariant();
// remove diacritics (accents)
value = RemoveDiacritics(value);
// ensure all word delimiters are hyphens
value = WordDelimiters.Replace(value, "-");
// strip out invalid characters
value = InvalidChars.Replace(value, "");
// replace multiple hyphens (-) with a single hyphen
value = MultipleHyphens.Replace(value, "-");
// trim hyphens (-) from ends
return value.Trim('-');
}
/// See: http://www.siao2.com/2007/05/14/2629747.aspx
private static string RemoveDiacritics(string stIn)
{
string stFormD = stIn.Normalize(NormalizationForm.FormD);
StringBuilder sb = new StringBuilder();
for (int ich = 0; ich < stFormD.Length; ich++)
{
UnicodeCategory uc = CharUnicodeInfo.GetUnicodeCategory(stFormD[ich]);
if (uc != UnicodeCategory.NonSpacingMark)
{
sb.Append(stFormD[ich]);
}
}
return (sb.ToString().Normalize(NormalizationForm.FormC));
}
}
Это все еще не решает проблему нелатинских символов. Совершенно альтернативным решением было бы использовать Uri.EscapeDataString для преобразования строки в ее шестнадцатеричное представление:
string original = "测试公司";
// %E6%B5%8B%E8%AF%95%E5%85%AC%E5%8F%B8
string converted = Uri.EscapeDataString(original);
Затем используйте данные для создания гиперссылки:
<a href="http://www.example.com/100/%E6%B5%8B%E8%AF%95%E5%85%AC%E5%8F%B8">
测试公司
</a>
Многие браузеры отображают китайские символы в адресной строке (см. Ниже), но, исходя из моего ограниченного тестирования, это не полностью поддерживается.
ПРИМЕЧАНИЕ. Чтобы Uri.EscapeDataString работал таким образом, iriParsing должен быть включен.
EDIT
Для тех, кто хочет генерировать URL-слагов в C #, я рекомендую проверить этот связанный вопрос:
Как Stack Overflow генерирует свои SEO-дружественные URL-адреса?
Это то, что я использовал для своего проекта.