使用正则表达式提取所有cookie属性

时间:2014-01-18 00:16:34

标签: c# regex f#

例如,如果我有一个cookie字符串

"lu=Rg3vHJ; Expires=Tue, 15-Jan-2013 21:47:38 GMT; Path=/; Domain=.example.com; HttpOnly"

如何提取以下列表中的所有cookie属性:

NameValuePair // Mandatory "lu" and "Rg3vHJ"
Domain // ".example.com"
Path // "/"
Expires // "Tue, 15-Jan-2013 21:47:38 GMT"
MaxAge // Not exist in the example
Secure // Not exist
HttpOnly // Exists

不确定“Set-Cookie”中属性的顺序是否固定。如果表达式可以按任何顺序丢失,如何编写表达式(除主名称/值对外,所有其他属性都可能丢失) )?

我需要将值分配给C#struct或F#record。

struct { 
    KeyValuePair<string, string> NameValue, // mandatory 
    string Domain,
    string Path,
    string Expires,
    string MaxAge,
    bool Secure,
    bool HttpOnly
}

F#

type Cookie = {
    NameValue : string * string;
    Domain : string option;
    Path : string option;
    Expires : string option;
    MaxAge : string;
    Secure : bool; // ? no associated value, anything better than bool
    HttpOnly : bool; // ? no associated value, anything better than bool
    }

2 个答案:

答案 0 :(得分:5)

string cookie = "lu=Rg3vHJ; Expires=Tue, 15-Jan-2013 21:47:38 GMT; Path=/; Domain=.example.com; HttpOnly";
var parts = cookie.Split(';')
            .Select(x => x.Split('='))
            .ToDictionary(x => x[0].Trim(), x => x.Length > 1 ? x[1].Trim() : "");

Console.WriteLine(String.Join(Environment.NewLine, parts.Select(x => x.Key + "=" + x.Value)));

或使用您在评论中发布的正则表达式

var pattern = @"(.+?)(?:=(.+?))?(?:;|$|,(?!\s))";

var parts = Regex.Matches(cookie, pattern).Cast<Match>()
                 .ToDictionary(m => m.Groups[1].Value, m => m.Groups[2].Value);

答案 1 :(得分:1)

我会将cookie更改为class,因为我将在LINQ中使用它。我还将NameValue更改为字典(以存储所有不匹配的属性):

class Cookie { 
    public Dictionary<string, string> NameValue; // mandatory 
    public string Domain;
    public string Path;
    public string Expires;
    public string MaxAge;
    public bool Secure;
    public bool HttpOnly;
}

然后使用Reflection和LINQ组合将命名属性和其他所有内容填充到字典中:

Cookie c = new Cookie();
c.NameValue = new Dictionary<string,string>();
Regex.Matches(cookie, @"(\w+)=?([^;]*)")
                .OfType<System.Text.RegularExpressions.Match>()
                .Select(m => new 
                {
                    Key = m.Groups[1].Value,
                    Value = m.Groups.Count > 2 ? m.Groups[2].Value : null,
                    Field = typeof(Cookie).GetField(m.Groups[1].Value)
                })
                .ToList()
                .ForEach(x =>
                {
                    if (x.Field != null)
                        x.Field.SetValue(c, 
                                    x.Field.FieldType != typeof(bool) ?
                                    (object)x.Value : true
                                    );
                    else
                        c.NameValue.Add(x.Key, x.Value);
                });