Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 753
  • Last Modified:

Best way to get a nameValueCollection from a string

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
M0m0nga
Asked:
M0m0nga
  • 4
  • 3
  • 3
  • +1
3 Solutions
 
gregoryyoungCommented:
well to make it into a name value collection wouldnt you just need to split on ; and = ? that shouldn't be much code....

0
 
gregoryyoungCommented:
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
 
drichardsCommented:
>> 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
Veeam and MySQL: How to Perform Backup & Recovery

MySQL and the MariaDB variant are among the most used databases in Linux environments, and many critical applications support their data on them. Watch this recorded webinar to find out how Veeam Backup & Replication allows you to get consistent backups of MySQL databases.

 
drichardsCommented:
Looks like the Split method has already been suggested...
0
 
M0m0ngaAuthor Commented:
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
 
gregoryyoungCommented:
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
 
M0m0ngaAuthor Commented:
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
 
M0m0ngaAuthor Commented:
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
 
gregoryyoungCommented:
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
 
drichardsCommented:
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
 
ajitanandCommented:
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
 
ajitanandCommented:
And this is much much faster than using regexpressions for this trivial task!!!

-Ajit Anand
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 4
  • 3
  • 3
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now