Solved

Best way to get a nameValueCollection from a string

Posted on 2004-09-06
13
724 Views
Last Modified: 2012-06-21
Right now I am writing a messy function which takes a string like this:

"Server=bigpc;Database=saleo;UID=bob; PWD=kevin123;Connect Timeout=60;"

splits it into an array of strings and tries to put each nameValuePair into a nameValueCollection.

My question is, is there a simpler/quicker/neater/standarder way to do this?

I know you can do this:
Dim nvc As New NameValueCollection(Request.QueryString)

So I tried to make the string look exactly like a valid query string and stick it in there but it doesn't work.

So is there a better way? using another object (not nvc) is fine. Thanks.
0
Comment
Question by:M0m0nga
  • 4
  • 3
  • 3
  • +1
13 Comments
 
LVL 37

Expert Comment

by:gregoryyoung
ID: 11993296
well to make it into a name value collection wouldnt you just need to split on ; and = ? that shouldn't be much code....

0
 
LVL 37

Expert Comment

by:gregoryyoung
ID: 11993300
string [] foo = yourstring.split(";");
foreach(string f in foo) {
     string [] tmp = f.split("=");
     tmp.Count should equal 2 0 is name, 1 is value.
}
0
 
LVL 19

Expert Comment

by:drichards
ID: 11993320
>> So I tried to make the string look exactly like a valid query string and stick it in there but it doesn't work.

Request.QueryString is a NameValueCollection so the constructor you used above will work.  Simply making a string in the same format will not work, so you're stuck with some manual parsing of the string if you want to get it into a NameValueCollection.  Here's one way using regular expressions:

        Dim reg As System.Text.RegularExpressions.Regex = New System.Text.RegularExpressions.Regex("([^\s].+?)=(.+?);", System.Text.RegularExpressions.RegexOptions.None)
        Dim mc As System.Text.RegularExpressions.MatchCollection = reg.Matches("Server=bigpc;Database=saleo;UID=bob; PWD=kevin123;Connect Timeout=60;")
        Dim nvc As New System.Collections.Specialized.NameValueCollection
        For Each m As System.Text.RegularExpressions.Match In mc
            nvc.Add(m.Groups.Item(1).Value, m.Groups.Item(2).Value)
        Next

If the space before 'PWD' in the example string was a typo, you can remove the [^\s], including the square brackets, from the regex expression.  You could also use the Split function of String:

        Dim nvc As New System.Collections.Specialized.NameValueCollection
        Dim ex As String = "Server=bigpc;Database=saleo;UID=bob; PWD=kevin123;Connect Timeout=60;"
        Dim prs() As String = ex.Split(";")
        For Each s As String In prs
            If s.Length > 0 Then
                Dim nv() As String = s.Split("=")
                nvc.Add(nv(0).Trim(), nv(1))
            End If
        Next
0
3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

 
LVL 19

Expert Comment

by:drichards
ID: 11993321
Looks like the Split method has already been suggested...
0
 
LVL 1

Author Comment

by:M0m0nga
ID: 11993569
thanks all,

Yes, as i said, i'm already using split in my 'messy' function. I should have posted my current code in the first place, sorry.

What i'm already using is:

      Dim arr As String() = thatOriginalString.Split(";")

      Dim nvc As New NameValueCollection(arr.Length)

      Dim i As Integer
      For i = 0 To arr.Length - 1 Step 2
            nvc.Add(arr(i), arr(i + 1))
      Next

I just hoped with all the groovy bits in the .NET BCL their might be something that does it in one or two lines.

So, back to the original question, can anybody find a better solution?

0
 
LVL 37

Expert Comment

by:gregoryyoung
ID: 11998747
umm that code wont work ...

Imports System.Threading
Imports System.Collections.Specialized
Module Module1



    Sub Main()
        Dim arr As String() = "Server=bigpc;Database=saleo;UID=bob; PWD=kevin123;Connect Timeout=60;".Split(";")


        Dim nvc As New NameValueCollection(arr.Length)

        Dim i As Integer
        For i = 0 To arr.Length - 1 Step 2
            nvc.Add(arr(i), arr(i + 1))
        Next

        For cnt As Integer = 0 To nvc.Count - 1
            Console.WriteLine(" key = " & nvc.Keys(cnt) & "    value = " & nvc(cnt))
        Next
    End Sub

End Module

 key = Server=bigpc    value = Database=saleo
 key = UID=bob    value =  PWD=kevin123
 key = Connect Timeout=60    value =
Press any key to continue

your code should be ...

Imports System.Threading
Imports System.Collections.Specialized
Module Module1



    Sub Main()
        Dim arr As String() = "Server=bigpc;Database=saleo;UID=bob; PWD=kevin123;Connect Timeout=60;".Split(";")


        Dim nvc As New NameValueCollection(arr.Length)

        Dim i As Integer
        For i = 0 To arr.Length - 1
            Dim foo() As String = arr(i).Split("=")
            If foo.Length = 2 Then
                nvc.Add(foo(0), foo(1))
            End If
        Next

        For cnt As Integer = 0 To nvc.Count - 1
            Console.WriteLine(" key = " & nvc.Keys(cnt) & "    value = " & nvc(cnt))
        Next
    End Sub

End Module

 key = Server    value = bigpc
 key = Database    value = saleo
 key = UID    value = bob
 key =  PWD    value = kevin123
 key = Connect Timeout    value = 60
Press any key to continue
0
 
LVL 1

Author Comment

by:M0m0nga
ID: 12001672
A) It does work. Its running fine. (Maybe you should try it)

B) gregoryyoung, your code is longer and more complex, not shorter and simpler.

For the third time, can anyone do what I am doing in my code sample in a a Shorter/Simpler way?
0
 
LVL 1

Author Comment

by:M0m0nga
ID: 12001819
My apologies gregoryyoung, I left out some earlier lines of code, turns out they where important.

Sorry to confuse you, thanks for trying to help.

Meanwhile, nobody has come up with a solution even nearly as good as my original code (the code I think is messy, and want to simplify/shorten). Here it is again:





Private Function logonFromConnectionString() As NameValueCollection
 Dim cs As String = ConfigurationSettings.AppSettings("dbConn")
 'dbconn is something like:
 'Server=aserver; Database=somedb; UID=someuid; PWD=somepass; Connect Timeout=60;"

 cs = cs.Replace(" ", "")
 cs = cs.Replace("=", ";")
 cs = cs.Trim(";")
 Dim arr As String() = cs.Split(";")

 Dim nvc As New NameValueCollection(arr.Length)

 Dim i As Integer
 For i = 0 To arr.Length - 1 Step 2
       nvc.Add(arr(i), arr(i + 1))
 Next

 Return nvc
End Function



Any ideas?

0
 
LVL 37

Assisted Solution

by:gregoryyoung
gregoryyoung earned 20 total points
ID: 12002035
1       Dim arr As String() = "Server=bigpc;Database=saleo;UID=bob; PWD=kevin123;Connect Timeout=60;".Split(";")
2       Dim nvc As New NameValueCollection(arr.Length)
3        For i as integer = 0 To arr.Length - 1
4            Dim foo() As String = arr(i).Split("=")
5            If foo.Length = 2 Then
6                nvc.Add(foo(0), foo(1))
7            End If
8        Next

1 dim cs  = "Server=bigpc;Database=saleo;UID=bob; PWD=kevin123;Connect Timeout=60;"
2 cs = cs.Replace(" ", "")
3 cs = cs.Replace("=", ";")
4 cs = cs.Trim(";")
5 Dim arr As String() = cs.Split(";")
6 Dim nvc As New NameValueCollection(arr.Length)
7 For i = 0 as integer To arr.Length - 1 Step 2
8      nvc.Add(arr(i), arr(i + 1))
9 Next

key parts of both ... perhaps I am missing something here as to how one is significantly longer or more complex? it seems to me like both are really 8 lines of code ..

yours could be shorter by saying
dim arr as string() = cs.replace(" ", "").Replace("=",";").Trim(";").Split(";")

but that seems rather convoluted

as for one solution being better than another ... I would atleast bother bounds checking i in your example (and making sure the length isnt odd or else you will fail)

given what these are doing I would say neither is overly complex (try doing it in C)

0
 
LVL 19

Assisted Solution

by:drichards
drichards earned 110 total points
ID: 12002224
Well, heck, if we're counting lines of code :)

1        Dim reg As System.Text.RegularExpressions.Regex = New System.Text.RegularExpressions.Regex("([^\s].+?)=(.+?);", System.Text.RegularExpressions.RegexOptions.None)
2        Dim mc As System.Text.RegularExpressions.MatchCollection = reg.Matches("Server=bigpc;Database=saleo;UID=bob; PWD=kevin123;Connect Timeout=60;")
3        Dim nvc As New System.Collections.Specialized.NameValueCollection
4        For Each m As System.Text.RegularExpressions.Match In mc
5            nvc.Add(m.Groups.Item(1).Value, m.Groups.Item(2).Value)
6        Next

Seems like even adding a line to check if there are two groups (though I think it won't match otherwise) it's still shorter than 8...

But in all seriousness, I don't see a more compact way of doing this than about this many lines of code - Split or Regex.
0
 
LVL 5

Accepted Solution

by:
ajitanand earned 110 total points
ID: 12109745
Here is something even smaller, and even faster that splitting twice and creating arrays multiple times!
------------------------------------
1            Dim thatOriginalString As String = "Server=bigpc;Database=saleo;UID=bob; PWD=kevin123;Connect Timeout=60;"
2            Dim arr As String() = thatOriginalString.Split(New Char() {";"c, "="c})
3            Dim nvc As New System.Collections.Specialized.NameValueCollection()
4            Dim i As Integer
5            For i = 0 To arr.Length - 2 Step 2
6                  nvc.Add(arr(i), arr(i + 1))
7            Next
------------------------------------

rgds,
Ajit Anand
0
 
LVL 5

Expert Comment

by:ajitanand
ID: 12109753
And this is much much faster than using regexpressions for this trivial task!!!

-Ajit Anand
0

Featured Post

DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

More often than not, we developers are confronted with a need: a need to make some kind of magic happen via code. Whether it is for a client, for the boss, or for our own personal projects, the need must be satisfied. Most of the time, the Framework…
Wouldn’t it be nice if you could test whether an element is contained in an array by using a Contains method just like the one available on List objects? Wouldn’t it be good if you could write code like this? (CODE) In .NET 3.5, this is possible…
Email security requires an ever evolving service that stays up to date with counter-evolving threats. The Email Laundry perform Research and Development to ensure their email security service evolves faster than cyber criminals. We apply our Threat…

831 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question