Solved

Best way to get a nameValueCollection from a string

Posted on 2004-09-06
13
705 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
 
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
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
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

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

Suggested Solutions

In my previous two articles we discussed Binary Serialization (http://www.experts-exchange.com/A_4362.html) and XML Serialization (http://www.experts-exchange.com/A_4425.html). In this article we will try to know more about SOAP (Simple Object Acces…
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…
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

708 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

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now