it-swarm.cn

如何在创建友好URL时删除无效字符(即如何创建slug)?

说我有这个网页:http://ww.xyz.com/Product.aspx?CategoryId=1

如果CategoryId = 1的名称是“Dogs”,我想将URL转换为如下所示:http://ww.xyz.com/Products/Dogs

问题是如果类别名称包含外来(或对于URL无效)字符。如果CategoryId = 2的名称是“Göraäldre”,那么新的URL应该是什么?

逻辑上它应该是:http://ww.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

6
Anthony

我想出了以下两种扩展方法(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 source中的这段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

您可以向Products表添加一个新字段,其中包含每个产品的URL安全且唯一的名称。这可能最初是自动生成的(用最接近的安全等价物替换非安全字符 - gora-aldre?)然后根据需要进行微调。

由于非安全字符的替换不是(总是)可逆的,所以在运行中做这种事情并不完全可行。

或者,您可以这样构建URL:

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

其中safe-string即时创建,根据需要替换不安全的字符。数字1234是产品密钥。您使用密钥查找产品,'safe-string'对用户和搜索引擎来说更多。

1
Kris

要记住两件事:

  1. URL重写通常不会对搜索引擎产生积极影响(通常是负面影响) - 因此,只有当您知道对用户满意度产生可衡量的积极影响时才应该这样做(并相应地:使您的URL对用户有用) 。

  2. 如果你决定进行URL重写,你必须完美地删除技术细节。例如,您永远不应该有多个显示相同内容的唯一网址。确保使用UTF-8进行非ASCII内容的编码,使用内容中的转义链接,并通常在各种浏览器上进行测试,以确保按计划运行。如果这对您来说是陌生的,那么我强烈建议您暂时不进行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. 逐个字符地运行输入字符串。
  4. 根据你拥有的内置函数,在每个字符上执行#1和#2而不是整个字符串可能会更快。
  5. 如果字符在a-z-9的范围内,请将其添加到新字符串中,否则:
    a)如果你的新字符串末尾已经连字符,请忽略它
    b)如果没有,请在字符串的末尾添加连字符。
  6. 当你走到最后,删除和领导或尾随连字符,你就完成了!
1
DisgruntledGoat

由于您发布了标记为ASP.Net: 查看此站点 ,它包含示例代码,用替换(大多数)文本与变音符号(您称之为无效字符)及其基本字符。

正如Kris所提到的,在您的网址中使用唯一ID,就像这个网站一样。如果您无法控制提供给您的ID,则应创建一个包含唯一ID的转换表,以及外部唯一ID。这样,当外部ID发生变化时,您的内部引用也很好。与您的唯一ID一起,您可以存储“搜索和人工优化ID”,这个ID不是那么独特,但看起来不错。

0
GvS

维基百科经常在其URL中使用非latin1字符。没有理由(除了您的网络服务器不支持它们)您不应该使用这些URL。

然而;如果你必须避免这些字符,我发现用非- 变音符号 形式替换它们。阅读这些内容的大多数人可以(从上下文)告诉词应该是什么,即使已经删除了变音符号。

0
Greg B