2017-04-11 2 views
1

J'essaie d'analyser RFC 2822 en utilisant fparsec mais je suis incapable de gérer les en-têtes avec plusieurs lignes: (il se confond avec l'en-tête suivant): Voici mon meilleur essai: faire vous avez des conseils?fparsec rfc2822 analyser plusieurs lignes d'en-tête

let str (s:string) = pstring s 

let stringLiteral = 
    manySatisfy (fun c -> c <> ':' && c <> '\r' && c <> '\n') 

let ws = many (pchar ' ') 

let keyValueSimple = stringLiteral .>>. (ws >>. str ":" >>. ws >>. stringLiteral) .>>. pchar '\n' |>> (fun (a,b) -> a) 

let lineValue = ws >>. stringLiteral .>>. (pchar '\n' .>>. (pchar '\t')) |>> (fun (a,b) -> a) 

let lastValue = ws >>. stringLiteral .>>. (pchar '\n' .>> notFollowedBy (pchar '\t')) |>> (fun (a,b) -> a) 

let keyValueComplex = stringLiteral .>>. (ws >>. pchar ':') .>>. (many lineValue) .>>. lastValue |>> (fun (((f),d),b) -> (f,f))      

let headers = many1 (keyValueComplex) 

let parse (fileName:string) = 
    test headers "Return-Path: <[email protected]>\n\twerwe\nDelivered-To: [email protected]\n " 

Je me attends \ t à 3,1: Delivered-To: [email protected]

Répondre

1

jamais l'esprit, il semble que je devais revenir en arrière (en utilisant tentative) pour que l'analyseur non pour toujours attendre un \ t mais chercher plutôt l'en-tête suivant.

let keyValueComplex = chaine littérale. >>. (ws >>. pchar ':'). >>. (many (try lineValue)). >>. lastValue | >> (fun (((g, h)), d), b) -> (g, (Seq.fold (+) "" d) + b))

Cela donne maintenant:

Success: [("Return-Path", "<[email protected]> werwe"); ("Delivered-To", "[email protected]")]