例如,如果我有一个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
}
答案 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);
});