Many thanks people.
I think I have the hang now.

By on 3/22/2011 1:49 PM ()

Hi,

I guess you want to split this in a Sequence of Lists(? or Sequences too?) of Tuples (Part * Value) eg.

{[("Par1","aaaa"); ("Par2"; "bbbb"); ... ]; ... }

right? I think you cant split into Tuples because you might get 4 Parts or 5 Parts or whatever (the Parx indicates this IMO).

Here is my solution for this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
 

let lines =
    [
        use file = System.IO.File.OpenText(@"c:\Temp\Testini.txt")
        while not file.EndOfStream do yield file.ReadLine()
    ]

type IniValue = { Part : string; Value : string }
type Connection = { Name : string; Values : IniValue list }

let connections =
    let rec scanLines lines curName curAcc resultAcc =
        let attachCurrent() =
            if Option.isSome curName
            then { Name = curName.Value; Values = List.rev curAcc }::resultAcc
            else resultAcc
        match lines with
        | [] -> attachCurrent()
        | l1::"Connection success"::rest ->
            let split = l1.Split(' ')
            match l1.Split(' ') with
            | [| "Open"; "connection"; name |] -> scanLines rest (Some name) [] (attachCurrent())
            | _ -> scanLines rest None [] resultAcc // ignore invalid "Open connection" and find the next valid
        | l::rest ->
            match l.Split(':') with
            | [| part; value |] -> scanLines rest curName ({ Part = part; Value = value }::curAcc) resultAcc
            | _ -> scanLines rest curName curAcc resultAcc // ignore invalid Part/Value entries
    List.rev <| scanLines lines None [] []

c:\Temp\Testini.txt is just your sample-data above pasted into a txt-file

By on 3/22/2011 12:28 AM ()

Here is my attempt - no error checking done though.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
open System
open System.IO
open System.Text.RegularExpressions 

// Splits a colon separated word into a (key, value) tuple 
let psplit(param:string) = (param.Split(':').[0], param.Split(':').[1])

// Splits a piece of text into multiple lines, removing blank lines in the process
let lsplit(txt:string) = 
    txt.Split([|Environment.NewLine|], StringSplitOptions.None ) 
    |> Seq.filter (fun a -> a.Trim() <> "")

let parse = 
    File.ReadAllText(<your file name here>)
    |> fun alltext -> Regex.Split(alltext, "Open connection")
    |> Seq.skip 1 // Discard the text before the first "Open connection"
    |> Seq.map (fun fragment -> lsplit(fragment) ) // Split into lines
    |> Seq.map (fun prm -> (Seq.head prm, // The string xxxxx following the 'open connection'
                            prm           // Parse the remaining 'Par' statements
                            |> Seq.skip 2 // Start from the first parameter   
                            |> Seq.map(fun parameter -> psplit(parameter))))
    |> Seq.iter (fun (cnxn, prms) -> 
                        printf "Connection : %s\n" cnxn
                        printf "Parameters : \n"
                        prms |> Seq.iter(fun param -> printf "%A\n" param))
       
By on 3/22/2011 2:12 AM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper