我有Cookie
的以下记录。
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
}
我需要将set-cookie
字符串转换为CookieAttricute list
。
let GetCookie str =
let (|ParseRegex|_|) regex str =
let m = Regex(regex, RegexOptions.IgnoreCase).Match(str)
if m.Success
then Some (List.tail [ for x in m.Groups -> x.Value ])
else None
match str with
| ParseRegex @"(.+?)(?:=(.+?))?(?:;|$|,(?!\s))" [name; value] ->
.... // How to construct a Cookie here?
| _ -> None
例如,给定以下字符串。
"ObSSOCookie=93KRPo;secure; httponly; path=/; domain=.xyz.com"
该功能应该返回
{ NameValue = ("ObSSOCookie", "93KRPo");
Secure = true;
HttpOnly = true;
Path = Some("/");
Domain = Some(".xyz.com");
MaxAge = None;
Expires = None }
答案 0 :(得分:1)
首先,我会使用String.Split
而不是使用正则表达式过度复杂化。然后,我将为属性构建Map<string, string>
。像这样:
let GetCookie (str: string) =
let allkeyvalues =
str.Split ';'
|> Array.map (fun str ->
match str.Split '=' with
| [| key |] -> (key, "")
| [| key; value |] -> (key, value)
| _ -> (* there's more than one '='; the format is incorrect. *))
let namevalue = allkeyvalues.[0]
let attributes =
Seq.skip 1 allkeyvalues
|> Seq.map (fun (key, value) ->
(key.ToLower(), value)) // attribute names are case-insensitive
|> Map.ofSeq
{
NameValue = namevalue
Secure = Map.containsKey "secure" attributes
Path = Map.tryFind "path" attributes
// etc...
}