C#中的URL Slugify算法?

cha*_*rit 74 c# slug

所以我搜索并浏览了SO上的slug标签,发现了两个引人注目的解决方案:

这只是部分解决问题的方法.我可以自己手动编写代码,但我很惊讶还没有解决方案.

那么,在C#和/或.NET中是否有一个slugify alrogithm实现正确解决了拉丁字符,unicode和其他各种语言问题?

小智 148

http://predicatet.blogspot.com/2009/04/improved-c-slug-generator-or-how-to.html

public static string GenerateSlug(this string phrase) 
{ 
    string str = phrase.RemoveAccent().ToLower(); 
    // invalid chars           
    str = Regex.Replace(str, @"[^a-z0-9\s-]", ""); 
    // convert multiple spaces into one space   
    str = Regex.Replace(str, @"\s+", " ").Trim(); 
    // cut and trim 
    str = str.Substring(0, str.Length <= 45 ? str.Length : 45).Trim();   
    str = Regex.Replace(str, @"\s", "-"); // hyphens   
    return str; 
} 

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

  • 请...不要使用`RemoveAccent`.检查这个问题,了解如何"RemoveDiacritics".http://stackoverflow.com/questions/249087/how-do-i-remove-diacritics-accents-from-a-string-in-net (11认同)
  • 解决方案不适用于非拉丁字母.RemoveAccent方法将删除例如西里尔字符.尝试像RemoveAccent("Неработает")这样的结果,结果将是空字符串:D (10认同)
  • 长度和截断超过45个字符的目的是什么? (6认同)

Joa*_*ron 18

在这里,您可以找到一种在c#中生成url slug的方法.此函数删除所有重音(Marcel的答案),替换空格,删除无效字符,从末尾修剪破折号并替换" - "或"_"的双重出现

码:

public static string ToUrlSlug(string value){

        //First to lower case
        value = value.ToLowerInvariant();

        //Remove all accents
        var bytes = Encoding.GetEncoding("Cyrillic").GetBytes(value);
        value = Encoding.ASCII.GetString(bytes);

        //Replace spaces
        value = Regex.Replace(value, @"\s", "-", RegexOptions.Compiled);

        //Remove invalid chars
        value = Regex.Replace(value, @"[^a-z0-9\s-_]", "",RegexOptions.Compiled);

        //Trim dashes from end
        value = value.Trim('-', '_');

        //Replace double occurences of - or _
        value = Regex.Replace(value, @"([-_]){2,}", "$1", RegexOptions.Compiled);

        return value ;
    }
Run Code Online (Sandbox Code Playgroud)


dan*_*ana 12

这是我的演绎,以Joan和Marcel的答案为基础.我所做的更改如下:

  • 使用广泛接受的方法删除重音.
  • 显式的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));
    }
}
Run Code Online (Sandbox Code Playgroud)

这仍然无法解决非拉丁字符问题.一个完全替代的解决方案是使用Uri.EscapeDataString将字符串转换为十六进制表示:

string original = "????";

// %E6%B5%8B%E8%AF%95%E5%85%AC%E5%8F%B8
string converted = Uri.EscapeDataString(original);
Run Code Online (Sandbox Code Playgroud)

然后使用数据生成超链接:

<a href="http://www.example.com/100/%E6%B5%8B%E8%AF%95%E5%85%AC%E5%8F%B8">
    ????
</a>
Run Code Online (Sandbox Code Playgroud)

许多浏览器会在地址栏中显示中文字符(见下文),但根据我的有限测试,它并不完全支持.

地址栏有汉字

注意:为了使Uri.EscapeDataString以这种方式工作,必须启用iriParsing.


编辑

对于那些希望在C#中生成URL Slugs的人,我建议您查看以下相关问题:

Stack Overflow如何生成其SEO友好的URL?

这是我最终用于我的项目.


Mat*_*ves 5

我在slugification(新词!)方面遇到的一个问题是冲突。例如,如果我有一篇名为“Stack-Overflow”的博客文章和一篇名为“Stack Overflow”的博客文章,那么这两个标题的标题是相同的。因此,我的 slug 生成器通常必须以某种方式涉及数据库。这可能就是为什么您看不到更多通用解决方案的原因。

  • 就我个人而言,我更喜欢在 slugs 后面附加唯一标识符(即整数)以确保它们是唯一的。这不是最友好的解决方案,但它可以帮助我避免麻烦。 (6认同)