将标题转换为虚线URL友好字符串

我想编写一个C#方法,将任何标题转换为URL友好字符串,类似于stackoverflow的作用:

  • 用破折号替换空格
  • 删除括号
  • 等等

我正在考虑按照RFC 3986标准(来自维基百科 )删除保留字符,但我不知道这是否足够? 这会使链接变得可行,但是有人知道堆栈溢出时其他字符被替换了吗? 我不希望在我的url中以%-s结尾…

目前的实施

string result = Regex.Replace(value.Trim(), @"[!*'""`();:@&+=$,/\\?%#\[\]«»{}_]"); return Regex.Replace(result.Trim(), @"[\s*[\-–—\s]\s*]", "-"); 

我的问题

  1. 我应该删除哪些字符?
  2. 我应该限制结果字符串的最大长度吗?
  3. 任何人都知道SO上的标题适用哪些规则?

一个子问题
即使它的编程相关,我是否应该将此问题移至元?

没有寻找要替换的东西,而不是未预留的字符列表是如此之短 ,它将成为一个很好的清晰正则表达式。

 return Regex.Replace(value, @"[^A-Za-z0-9_\.~]+", "-"); 

(请注意,我没有在允许的字符列表中包含短划线;这是因为它被“1或更多”运算符[ + ]吞噬,因此多个破折号(在原始或生成或组合中)被折叠,根据Dominic Rodger的优点。)

您可能还想删除常用词(“the”,“an”,“a”等),尽管这样做可能会略微改变句子的含义。 可能还想删除任何尾随破折号和句号。

还强烈建议您执行SO和其他人所做的操作,并包含标题以外的唯一标识符,然后在处理URL时仅使用该唯一ID。 所以http://example.com/articles/1234567/is-the-pop-catholic (注意缺少’e’)和http://example.com/articles/1234567/is-the-pope-catholic解析为相同的资源。

我会这样做:

 string url = title; url = Regex.Replace(url, @"^\W+|\W+$", ""); url = Regex.Replace(url, @"'\"", ""); url = Regex.Replace(url, @"_", "-"); url = Regex.Replace(url, @"\W+", "-"); 

基本上这是做什么的:

  • 从标题的开头和结尾删除非单词字符;
  • 删除单引号和双引号(主要是为了摆脱单词中间的撇号);
  • 用连字符替换下划线(下划线在技术上是一个单词字符以及数字和字母); 和
  • 用单个连字符替换所有非单词字符组。

大多数“sluggifiers”(转换为friendly-url类型名称的方法)倾向于执行以下操作:

  1. 除了空格,短划线,下划线和字母数字之外的所有内容。
  2. (可选)删除“常用词”(a,a,an,of等)。
  3. 用短划线替换空格和下划线。
  4. (可选)转换为小写。

据我所知,StackOverflow的缓冲器执行#1,#3和#4,但不执行#2。

这个怎么样:

 string FriendlyURLTitle(string pTitle) { pTitle = pTitle.Replace(" ", "-"); pTitle = HttpUtility.UrlEncode(pTitle); return Regex.Replace(pTitle, "\%[0-9A-Fa-f]{2}", ""); } 

这就是我目前的说法。

  public static string Slug(this string value) { if (value.HasValue()) { var builder = new StringBuilder(); var slug = value.Trim().ToLowerInvariant(); foreach (var c in slug) { switch (c) { case ' ': builder.Append("-"); break; case '&': builder.Append("and"); break; default: if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') && c != '-') { builder.Append(c); } break; } } return builder.ToString(); } return string.Empty; } 

我用这个……

  public static string ToUrlFriendlyString(this string value) { value = (value ?? "").Trim().ToLower(); var url = new StringBuilder(); foreach (char ch in value) { switch (ch) { case ' ': url.Append('-'); break; default: url.Append(Regex.Replace(ch.ToString(), @"[^A-Za-z0-9'()\*\\+_~\:\/\?\-\.,;=#\[\]@!$&]", "")); break; } } return url.ToString(); } 

这对我有用

 string output = Uri.UnescapeDataString(input);