func SubmatchMap(re *regexp.Regexp, str string) (dict map[string]string) {
	dict = make(map[string]string)
	names := re.SubexpNames()
	matches := re.FindStringSubmatch(str)
	if len(names) > 0 && len(matches) > 0 {
		names = names[1:]
		matches = matches[1:]
		for i, name := range names {
			dict[name] = matches[i]  
		}
	}
	return dict
}
SubmatchMap returns a map of submatch names to their captures, if any.
If no matches are found, it returns an empty dict.
Submatch names are specified using (?P<name>[matchme])
package chkutil
import (
	"bytes"
	"crypto/tls"
	"errors"
	"github.com/CiscoCloud/distributive/errutil"
	"github.com/CiscoCloud/distributive/tabular"
	log "github.com/Sirupsen/logrus"
	"io/ioutil"
	"net/http"
	"os/exec"
	"regexp"
	"strconv"
	"strings"
)
type Check interface {
	New(parameters []string) (Check, error)
	Status() (code int, msg string, err error)
}
type MakeCheckT func() Check
var registry = map[string]MakeCheckT{}
func Register(name string, check MakeCheckT) {
    lname := strings.ToLower(name)
    registry[lname] = check
}
func LookupCheck(name string) Check {
    lname := strings.ToLower(name)
    if makeCheckFn, ok := registry[lname]; ok {
        return makeCheckFn()
    }
    return nil
}
func CommandOutput(cmd *exec.Cmd) string {
	out, err := cmd.CombinedOutput()
	outStr := string(out)
	if err != nil {
		errutil.ExecError(cmd, outStr, err)
	}
	return outStr
}
func CommandColumnNoHeader(col int, cmd *exec.Cmd) []string {
	out := CommandOutput(cmd)
	return tabular.GetColumnNoHeader(col, tabular.StringToSlice(out))
}
func SeparateByteUnits(str string) (int, string, error) {
	getByteUnits := func(str string) (string, error) {
		regexps := map[string]*regexp.Regexp{
			"tb": regexp.MustCompile(`tera(bytes){0,1}|[tT]{1}[iI]{0,1}[bB]{1}`),
			"gb": regexp.MustCompile(`giga(bytes){0,1}|[gG]{1}[iI]{0,1}[bB]{1}`),
			"mb": regexp.MustCompile(`mega(bytes){0,1}|[mM]{1}[iI]{0,1}[bB]{1}`),
			"kb": regexp.MustCompile(`kilo(bytes){0,1}|[kK]{1}[iI]{0,1}[bB]{1}`),
			"b":  regexp.MustCompile(`[^oa]bytes{0,1}|[^kKmMgGtT][bB]{1}`),
		}
		for unit, re := range regexps {
			if re.MatchString(str) {
				return unit, nil
			}
		}
		return "", errors.New("Couldn't extract byte units from string " + str)
	}
	integerFromString := func(str string) (int, error) {
		digitRe := regexp.MustCompile(`\d+`)
		intStr := digitRe.FindString(str)
		if intStr == "" {
			return 0, errors.New("Couldn't find integer in string")
		}
		actualInt, err := strconv.ParseInt(intStr, 10, 64)
		if err != nil {
			return 0, errors.New("Couldn't extract integer from string")
		}
		return int(actualInt), nil
	}
	unit, err := getByteUnits(str)
	if err != nil {
		return 1, "", err
	}
	scalar, err := integerFromString(str)
	if err != nil {
		return 1, "", err
	}
	return scalar, unit, nil
}