将标题转换为虚线URL友好字符串
我想编写一个C#方法,将任何标题转换为URL友好字符串,类似于stackoverflow的作用:
- 用破折号替换空格
- 删除括号
- 等等
我正在考虑按照RFC 3986标准(来自维基百科 )删除保留字符,但我不知道这是否足够? 这会使链接变得可行,但是有人知道堆栈溢出时其他字符被替换了吗? 我不希望在我的url中以%-s结尾…
目前的实施
string result = Regex.Replace(value.Trim(), @"[!*'""`();:@&+=$,/\\?%#\[\]«»{}_]"); return Regex.Replace(result.Trim(), @"[\s*[\-–—\s]\s*]", "-");
我的问题
- 我应该删除哪些字符?
- 我应该限制结果字符串的最大长度吗?
- 任何人都知道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类型名称的方法)倾向于执行以下操作:
- 除了空格,短划线,下划线和字母数字之外的所有内容。
- (可选)删除“常用词”(a,a,an,of等)。
- 用短划线替换空格和下划线。
- (可选)转换为小写。
据我所知,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);