Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将标题转换为虚线URL友好字符串_C#_Replace - Fatal编程技术网

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

C# 将标题转换为虚线URL友好字符串,c#,replace,C#,Replace,我想编写一个C#方法,将任何标题转换为URL友好字符串,类似于Stack Overflow所做的: 用破折号替换空格 删除括号 等等 我正在考虑按照RFC3986标准删除保留字符,但我不知道这是否足够?这将使链接可行,但有人知道stackoverflow正在替换哪些其他字符吗?我不想在我的URL中出现%s 当前实施 string result=Regex.Replace(value.Trim(),@“[!*”``();:@&+=$,/\\?%\\[\]«»{}; 返回Regex.Replac

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

  • 用破折号替换空格
  • 删除括号
  • 等等
我正在考虑按照RFC3986标准删除保留字符,但我不知道这是否足够?这将使链接可行,但有人知道stackoverflow正在替换哪些其他字符吗?我不想在我的URL中出现%s

当前实施
string result=Regex.Replace(value.Trim(),@“[!*”``();:@&+=$,/\\?%\\[\]«»{};
返回Regex.Replace(result.Trim(),@“[\s*[\----\s]\s*]”,“-”;
我的问题
  • 我应该删除哪些字符
  • 我应该限制结果字符串的最大长度吗
  • 有人知道什么规则适用于标题吗
  • 大多数“Sluggifer”(转换为友好url类型名称的方法)倾向于执行以下操作:

  • 除去所有空格、破折号、下划线和字母数字以外的内容
  • (可选)删除“常用词”(the、a、an、of等)
  • 用破折号替换空格和下划线
  • (可选)转换为小写
  • 据我所知,StackOverflow的Slaggifer能做到1、3和4,但不能做到2。

    我会:

    string url = title;
    url = Regex.Replace(url, @"^\W+|\W+$", "");
    url = Regex.Replace(url, @"'\"", "");
    url = Regex.Replace(url, @"_", "-");
    url = Regex.Replace(url, @"\W+", "-");
    
    基本上这是在做什么:

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

    与其寻找替换的东西,不如列出一个清晰的正则表达式

    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 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;
        }
    
    公共静态字符串Slug(此字符串值)
    {
    if(value.HasValue())
    {
    var builder=新的StringBuilder();
    var slug=value.Trim().ToLowerInvariant();
    foreach(段塞中的变量c)
    {
    开关(c)
    {
    案例“”:
    生成器。附加(“-”);
    打破
    案例“&”:
    建造商。附加(“和”);
    打破
    违约:
    如果((c>='0'&&c='a'&&c我用这个

        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);
    

    但是,白名单方法确实会阻止Unicode字符(在IRI中)通过。@Bobince:没错。我还必须提供与语言相关的字符(来自东欧字符集)@Robert:IRI(RFC3987;)更改游戏。如果这很重要,您可能希望在问题中提及它。将支持的IRI值添加到白名单似乎并不困难。对于外观很相似的人,您可能希望对其进行预筛选。@TJCrowder:不应该。(点)在您的正则表达式模式中是否被转义?@Robert:我不这么认为,但坦白地说,我不确定,必须进行检查。这样做是无害的,我已相应地编辑了答案。点(此处的任何字符)的通常含义在字符类构造中没有任何意义。您必须转义
    `
    (显然),
    -
    (因为它在构造中创建了一个范围)和
    ]
    (这将关闭它),但我认为你不必逃避大多数其他人。因此,我的替代品做的是相同的:1、3和4。我只需在第一个reg-ex模式中添加下划线。对不起,我宁愿使用正则表达式。你的许多代码行最多可以被两个正则表达式替换。是的,但是当正则表达式on非常复杂且难以理解。我宁愿使用可维护性,而不是2个神秘的正则表达式:)我想知道为什么这没有得到更多的选票?非常简单易懂,而且解释得很好。我还想知道,对于步骤2和步骤3,字符串.Replace是否会更快,这是一种普通的字符替换,但实际上并不存在。我还对^\W非单词字符在unicode和非拉丁语言中的性能感兴趣?如果有我认为这是最好的答案。最后的建议-我很喜欢前面的建议,用“and”替换“&”。哦-最后一件事,我认为在第三行(第二行。替换)中的“\\”应该是“@”“如果您可以发布单独的问题,而不是将您的问题合并为一个问题,这是首选。这样,它可以帮助回答您的问题的人,也可以帮助其他人寻找至少一个您的问题。
    string output = Uri.UnescapeDataString(input);