9

I have a string like A=B&C=D&E=F, how to parse it into map in golang?

Here is example on Java, but I don't understand this split part

String text = "A=B&C=D&E=F";
Map<String, String> map = new LinkedHashMap<String, String>();
for(String keyValue : text.split(" *& *")) {
   String[] pairs = keyValue.split(" *= *", 2);
   map.put(pairs[0], pairs.length == 1 ? "" : pairs[1]);
}
1
  • 2
    I think what you really want is url.ParseQuery. Commented Feb 27, 2016 at 0:05

4 Answers 4

11

Maybe what you really want is to parse an HTTP query string, and url.ParseQuery does that. (What it returns is, more precisely, a url.Values storing a []string for every key, since URLs sometimes have more than one value per key.) It does things like parse HTML escapes (%0A, etc.) that just splitting doesn't. You can find its implementation if you search in the source of url.go.

However, if you do really want to just split on & and = like that Java code did, there are Go analogues for all of the concepts and tools there:

  • map[string]string is Go's analog of Map<String, String>
  • strings.Split can split on & for you. SplitN limits the number of pieces split into like the two-argument version of split() in Java does. Note that there might only be one piece so you should check len(pieces) before trying to access pieces[1] say.
  • for _, piece := range pieces will iterate the pieces you split.
  • The Java code seems to rely on regexes to trim spaces. Go's Split doesn't use them, but strings.TrimSpace does something like what you want (specifically, strips all sorts of Unicode whitespace from both sides).

I'm leaving the actual implementation to you, but perhaps these pointers can get you started.

Sign up to request clarification or add additional context in comments.

Comments

10
import ( "strings" )

var m map[string]string
var ss []string

s := "A=B&C=D&E=F"
ss = strings.Split(s, "&")
m = make(map[string]string)
for _, pair := range ss {
    z := strings.Split(pair, "=")
    m[z[0]] = z[1]
}

This will do what you want.

1 Comment

A few differences from the original Java: 1) this will crash with index out of range when an item is missing a =, 2) this doesn't strip spaces around the delimiters, 3) anything after an = in the value part is dropped. Fine to do something similar rather than identical, just all bears noting (especially the crash).
0

There is a very simple way provided by golang net/url package itself.

Change your string to make it a url with query params text := "method://abc.xyz/A=B&C=D&E=F";

Now just pass this string to Parse function provided by net/url.

import (
    netURL "net/url"
)
u, err := netURL.Parse(textURL)
        if err != nil {
            log.Fatal(err)
        }

Now u.Query() will return you a map containing your query params. This will also work for complex types.

Comments

0

Here is a demonstration of a couple of methods:

package main

import (
   "fmt"
   "net/url"
)

func main() {
   {
      q, e := url.ParseQuery("west=left&east=right")
      if e != nil {
         panic(e)
      }
      fmt.Println(q) // map[east:[right] west:[left]]
   }
   {
      u := url.URL{RawQuery: "west=left&east=right"}
      q := u.Query()
      fmt.Println(q) // map[east:[right] west:[left]]
   }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.