需要將URL中的某個QueryString參數移除的函數,例如: 原本是httq://www.com/a.aspx?a=1&b=2&c=3,將b移除後要變成httq://www.com/a.aspx?a=1&c=3,分別用Regex及ParseQueryString試寫,因為要考慮b是第一個、最後一個及唯一參數情境下對?及&符號的需求不同,增加了程式的複雜度。

經簡單測試,二者效果相同。不過若考量Regex在遇到比對文字(即參數名稱)中出現Regular Expression特殊符號時會失效,我想ParseQueryString會是較好的選擇。

using System;
using System.Collections.Specialized;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] tests =
                {
                    "http://www.com",
                    "http://www.com/a?a=2",
                    "http://www.com/a.aspx?a=%3e&boo=2&c=3",
                    "http://www.com/a.aspx?boo=1&a=1",
                    "http://www.com/a.aspx?boo=2"
                };
            foreach (string line in tests)
            {
            Console.WriteLine("Source      = {0}", line);
            Console.WriteLine("Regex       : {0}", RemoveQueryParam1(line, "boo"));
            Console.WriteLine("HttpUtility : {0}", RemoveQueryParam2(line, "boo"));
                Console.WriteLine();
            }
            Console.Read();
        }
 
        //設法用RegularExpression比對抽換
        public static string RemoveQueryParam1(string url, string key)
        {
            return 
            Regex.Replace(url, "[?&]" + key + "=[^&]*[&]{0,1}",
                //若為&boo=...則直接去除,?boo=...&...則要傳回?
                //...&boo=...&...時要傳回&
            o => (o.Value.StartsWith("?") && o.Value.EndsWith("&") ? "?" : "") +
                (o.Value.StartsWith("&") && o.Value.EndsWith("&") ? "&" : "")
                );
        }
 
        //使用.NET內建機制
        public static string RemoveQueryParam2(string url, string key)
        {
            //拆出QueryString部分
    Uri uri = new Uri(url);
            if (string.IsNullOrEmpty(uri.Query)) return url;
            //用HttpUtility.ParseQueryString()將其解析為成對Name/Value集合
              //在ASP.NET中直接用Request.QueryString即可
    NameValueCollection args = HttpUtility.ParseQueryString(uri.Query);
            args.Remove(key);
            return url.Substring(0, url.IndexOf("?") + 
                    //若有參數就多加1
                   (args.Count > 0 ? 1 : 0)) +
                   string.Join("&",
                   //將NameValueCollection Cast<string>取得可LINQ的Keys集合
                               args.Cast<string>().Select(
                                   k => string.Format("{0}={1}", k, 
                                       HttpUtility.UrlEncode(args[k]))));
        }
    }
}

測試結果:

Source      = httq://www.com
Regex       : httq://www.com
httpUtility : httq://www.com

Source      = httq://www.com/a?a=2
Regex       : httq://www.com/a?a=2
httpUtility : httq://www.com/a?a=2

Source      = httq://www.com/a.aspx?a=%3e&boo=2&c=3
Regex       : httq://www.com/a.aspx?a=%3e&c=3
httpUtility : httq://www.com/a.aspx?a=%3e&c=3

Source      = httq://www.com/a.aspx?boo=1&a=1
Regex       : httq://www.com/a.aspx?a=1
httpUtility : httq://www.com/a.aspx?a=1

Source      = httq://www.com/a.aspx?boo=2
Regex       : httq://www.com/a.aspx
httpUtility : httq://www.com/a.aspx

Comments

# by Eric HUang

大大你有一行應該測試完之後沒改到 args.Remove("boo"); 應改為 args.Remove(key); 才對 ^^

# by Jeffrey

to Eric, 真的,我漏改了!! 謝謝提醒~~

Post a comment