Solved

Best way to get a nameValueCollection from a string

Posted on 2004-09-06
13
730 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
The New “Normal” in Modern Enterprise Operations

DevOps for the modern enterprise offers many benefits — increased agility, productivity, and more, but digital transformation isn’t easy, especially if you’re not addressing the right issues. Register for the webinar to dive into the “new normal” for enterprise modern ops.

 
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

Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

Question has a verified solution.

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

IP addresses can be stored in a database in any of several ways.  These ways may vary based on the volume of the data.  I was dealing with quite a large amount of data for user authentication purpose, and needed a way to minimize the storage.   …
This article shows how to deploy dynamic backgrounds to computers depending on the aspect ratio of display
Established in 1997, Technology Architects has become one of the most reputable technology solutions companies in the country. TA have been providing businesses with cost effective state-of-the-art solutions and unparalleled service that is designed…
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…

791 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