Regular expression matching with string slice in Go












2












$begingroup$


I have a slice of strings, and within each string contains multiple key=value formatted messages. I want to pull all the keys out of the strings so I can collect them to use as the header for a CSV file. I do not know all potential key fields, so I have to use regular expression matching to find them.



Here is my code.



package main

import (
"fmt"
"regexp"
)
func GetKeys(logs string) string {
// topMatches is the final array to be returned.
// midMatches contains no duplicates, but the data is `key=`.
// subMatches contains all initial matches.
// initialRegex matches for anthing that matches `key=`. this is because the matching patterns.
// cleanRegex massages `key=` to `key`
topMatches := string{}
midMatches := string{}
subMatches := string{}
initialRegex := regexp.MustCompile(`([a-zA-Z]{1,}=)`)
cleanRegex := regexp.MustCompile(`([a-zA-Z]{1,})`)

// the nested loop for matches is because FindAllString
// returns string
for _, i := range logs {
matches := initialRegex.FindAllString(i, -1)
for _, m := range matches {
subMatches = append(subMatches, m)
}
}

// remove duplicates.
seen := map[string]string{}
for _, x := range subMatches {
if _, ok := seen[x]; !ok {
midMatches = append(midMatches, x)
seen[x] = x
}
}
// this is where I remove the `=` character.
for _, y := range midMatches {
clean := cleanRegex.FindAllString(y, 1)
topMatches = append(topMatches, clean[0])
}
return topMatches
}


func main() {
y := string{"key=value", "msg=payload", "test=yay", "msg=payload"}
y = GetKeys(y)
fmt.Println(y)
}


I think my code is inefficient because I cannot determine how to properly optimise the initialRegex regular expression to match just the key in the key=value format without matching the value as well.



Can my first regular expression, initialRegex, be optimised so I do not have to do a second matching loop to remove the = character?



Playground: http://play.golang.org/p/ONMf_cympM










share|improve this question









$endgroup$












  • $begingroup$
    {1,} is equivalent to +, and if the Go regexp package supports it, you can use positive look-ahead to detect but not capture the =: [a-zA-Z]+(?==). IIRC, the second = doesn't need to be escaped since it has no special meaning outside of this context. Finally, I doubt you need the capturing group around the whole expression.
    $endgroup$
    – David Harkness
    Mar 6 '16 at 20:51
















2












$begingroup$


I have a slice of strings, and within each string contains multiple key=value formatted messages. I want to pull all the keys out of the strings so I can collect them to use as the header for a CSV file. I do not know all potential key fields, so I have to use regular expression matching to find them.



Here is my code.



package main

import (
"fmt"
"regexp"
)
func GetKeys(logs string) string {
// topMatches is the final array to be returned.
// midMatches contains no duplicates, but the data is `key=`.
// subMatches contains all initial matches.
// initialRegex matches for anthing that matches `key=`. this is because the matching patterns.
// cleanRegex massages `key=` to `key`
topMatches := string{}
midMatches := string{}
subMatches := string{}
initialRegex := regexp.MustCompile(`([a-zA-Z]{1,}=)`)
cleanRegex := regexp.MustCompile(`([a-zA-Z]{1,})`)

// the nested loop for matches is because FindAllString
// returns string
for _, i := range logs {
matches := initialRegex.FindAllString(i, -1)
for _, m := range matches {
subMatches = append(subMatches, m)
}
}

// remove duplicates.
seen := map[string]string{}
for _, x := range subMatches {
if _, ok := seen[x]; !ok {
midMatches = append(midMatches, x)
seen[x] = x
}
}
// this is where I remove the `=` character.
for _, y := range midMatches {
clean := cleanRegex.FindAllString(y, 1)
topMatches = append(topMatches, clean[0])
}
return topMatches
}


func main() {
y := string{"key=value", "msg=payload", "test=yay", "msg=payload"}
y = GetKeys(y)
fmt.Println(y)
}


I think my code is inefficient because I cannot determine how to properly optimise the initialRegex regular expression to match just the key in the key=value format without matching the value as well.



Can my first regular expression, initialRegex, be optimised so I do not have to do a second matching loop to remove the = character?



Playground: http://play.golang.org/p/ONMf_cympM










share|improve this question









$endgroup$












  • $begingroup$
    {1,} is equivalent to +, and if the Go regexp package supports it, you can use positive look-ahead to detect but not capture the =: [a-zA-Z]+(?==). IIRC, the second = doesn't need to be escaped since it has no special meaning outside of this context. Finally, I doubt you need the capturing group around the whole expression.
    $endgroup$
    – David Harkness
    Mar 6 '16 at 20:51














2












2








2


1



$begingroup$


I have a slice of strings, and within each string contains multiple key=value formatted messages. I want to pull all the keys out of the strings so I can collect them to use as the header for a CSV file. I do not know all potential key fields, so I have to use regular expression matching to find them.



Here is my code.



package main

import (
"fmt"
"regexp"
)
func GetKeys(logs string) string {
// topMatches is the final array to be returned.
// midMatches contains no duplicates, but the data is `key=`.
// subMatches contains all initial matches.
// initialRegex matches for anthing that matches `key=`. this is because the matching patterns.
// cleanRegex massages `key=` to `key`
topMatches := string{}
midMatches := string{}
subMatches := string{}
initialRegex := regexp.MustCompile(`([a-zA-Z]{1,}=)`)
cleanRegex := regexp.MustCompile(`([a-zA-Z]{1,})`)

// the nested loop for matches is because FindAllString
// returns string
for _, i := range logs {
matches := initialRegex.FindAllString(i, -1)
for _, m := range matches {
subMatches = append(subMatches, m)
}
}

// remove duplicates.
seen := map[string]string{}
for _, x := range subMatches {
if _, ok := seen[x]; !ok {
midMatches = append(midMatches, x)
seen[x] = x
}
}
// this is where I remove the `=` character.
for _, y := range midMatches {
clean := cleanRegex.FindAllString(y, 1)
topMatches = append(topMatches, clean[0])
}
return topMatches
}


func main() {
y := string{"key=value", "msg=payload", "test=yay", "msg=payload"}
y = GetKeys(y)
fmt.Println(y)
}


I think my code is inefficient because I cannot determine how to properly optimise the initialRegex regular expression to match just the key in the key=value format without matching the value as well.



Can my first regular expression, initialRegex, be optimised so I do not have to do a second matching loop to remove the = character?



Playground: http://play.golang.org/p/ONMf_cympM










share|improve this question









$endgroup$




I have a slice of strings, and within each string contains multiple key=value formatted messages. I want to pull all the keys out of the strings so I can collect them to use as the header for a CSV file. I do not know all potential key fields, so I have to use regular expression matching to find them.



Here is my code.



package main

import (
"fmt"
"regexp"
)
func GetKeys(logs string) string {
// topMatches is the final array to be returned.
// midMatches contains no duplicates, but the data is `key=`.
// subMatches contains all initial matches.
// initialRegex matches for anthing that matches `key=`. this is because the matching patterns.
// cleanRegex massages `key=` to `key`
topMatches := string{}
midMatches := string{}
subMatches := string{}
initialRegex := regexp.MustCompile(`([a-zA-Z]{1,}=)`)
cleanRegex := regexp.MustCompile(`([a-zA-Z]{1,})`)

// the nested loop for matches is because FindAllString
// returns string
for _, i := range logs {
matches := initialRegex.FindAllString(i, -1)
for _, m := range matches {
subMatches = append(subMatches, m)
}
}

// remove duplicates.
seen := map[string]string{}
for _, x := range subMatches {
if _, ok := seen[x]; !ok {
midMatches = append(midMatches, x)
seen[x] = x
}
}
// this is where I remove the `=` character.
for _, y := range midMatches {
clean := cleanRegex.FindAllString(y, 1)
topMatches = append(topMatches, clean[0])
}
return topMatches
}


func main() {
y := string{"key=value", "msg=payload", "test=yay", "msg=payload"}
y = GetKeys(y)
fmt.Println(y)
}


I think my code is inefficient because I cannot determine how to properly optimise the initialRegex regular expression to match just the key in the key=value format without matching the value as well.



Can my first regular expression, initialRegex, be optimised so I do not have to do a second matching loop to remove the = character?



Playground: http://play.golang.org/p/ONMf_cympM







parsing regex go






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Mar 4 '16 at 19:33









mxplusbmxplusb

22929




22929












  • $begingroup$
    {1,} is equivalent to +, and if the Go regexp package supports it, you can use positive look-ahead to detect but not capture the =: [a-zA-Z]+(?==). IIRC, the second = doesn't need to be escaped since it has no special meaning outside of this context. Finally, I doubt you need the capturing group around the whole expression.
    $endgroup$
    – David Harkness
    Mar 6 '16 at 20:51


















  • $begingroup$
    {1,} is equivalent to +, and if the Go regexp package supports it, you can use positive look-ahead to detect but not capture the =: [a-zA-Z]+(?==). IIRC, the second = doesn't need to be escaped since it has no special meaning outside of this context. Finally, I doubt you need the capturing group around the whole expression.
    $endgroup$
    – David Harkness
    Mar 6 '16 at 20:51
















$begingroup$
{1,} is equivalent to +, and if the Go regexp package supports it, you can use positive look-ahead to detect but not capture the =: [a-zA-Z]+(?==). IIRC, the second = doesn't need to be escaped since it has no special meaning outside of this context. Finally, I doubt you need the capturing group around the whole expression.
$endgroup$
– David Harkness
Mar 6 '16 at 20:51




$begingroup$
{1,} is equivalent to +, and if the Go regexp package supports it, you can use positive look-ahead to detect but not capture the =: [a-zA-Z]+(?==). IIRC, the second = doesn't need to be escaped since it has no special meaning outside of this context. Finally, I doubt you need the capturing group around the whole expression.
$endgroup$
– David Harkness
Mar 6 '16 at 20:51










2 Answers
2






active

oldest

votes


















3












$begingroup$

You're not making good use of regular expressions. A single regex can do the job:



pattern := regexp.MustCompile(`([a-zA-Z]+)=`)


The parentheses (...) are the capture the interesting part for you.



You can use result = pattern.FindAllStringSubmatch(s) to match a string against the regex pattern. The return value is a string, where in each string slice, the 1st element is the entire matched string, and the 2nd, 3rd, ... elements have the content of the capture groups. In this example we have one capture group (...), so the value of the key will be in item[1] of each string slice.



Instead of a map[string]string map for seen, a map[string]boolean would be more efficient.



Putting it together:



func GetKeys(logs string) string {
var keys string
pattern := regexp.MustCompile(`([a-zA-Z]+)=`)

seen := make(map[string]bool)
for _, log := range(logs) {
result := pattern.FindAllStringSubmatch(log, -1)
for _, item := range result {
key := item[1]
if _, ok := seen[key]; !ok {
keys = append(keys, key)
seen[key] = true
}
}
}

return keys
}


If the input strings are not guaranteed to be in the right format matching the pattern, then you might want to add a guard statement inside the main for loop, for example:



    if len(result) != 2 {
continue
}





share|improve this answer











$endgroup$













  • $begingroup$
    I was reading about submatches, but I wasn't entirely sure if that's what I wanted or not because I didn't understand that was for capture groups. That makes a lot of sense. What is more efficient about a boolean over the string?
    $endgroup$
    – mxplusb
    Mar 4 '16 at 20:32












  • $begingroup$
    @mynameismevin the storage of a bool is smaller than a string
    $endgroup$
    – janos
    Mar 6 '16 at 20:53










  • $begingroup$
    The original code used FindAllString to find multiple matches per message, but yours uses FindStringSubmatch which looks to return a single match.
    $endgroup$
    – David Harkness
    Mar 7 '16 at 21:36










  • $begingroup$
    A map[string]struct{} is even more efficient and uses less memory than map[string]bool.
    $endgroup$
    – OneOfOne
    Mar 28 '16 at 8:38










  • $begingroup$
    @OneOfOne really? how? and how would I change the line seen[key] = true to make that work?
    $endgroup$
    – janos
    Mar 28 '16 at 10:13



















0












$begingroup$

I know this is an old question but it popped up in my feed so I figured I'd contribute.



Out of curiosity, why use a regular expression at all? You could achieve the same thing use standard strings package and keep things simple. Here's a Playground that outputs the same result as your Playground.



package main

import (
"fmt"
"strings"
)

func GetKeys(logs string) string {
exists := make(map[string]bool)
keys := make(string, 0)
for _, log := range logs {
parts := strings.Split(log, "=")
if len(parts) >= 1 {
k := parts[0]
if !exists[k] {
keys = append(keys, k)
exists[k] = true
}
}
}
return keys
}

func main() {
y := string{"key=value", "msg=payload", "test=yay", "msg=payload"}
fmt.Println(GetKeys(y))
}





share|improve this answer









$endgroup$













    Your Answer





    StackExchange.ifUsing("editor", function () {
    return StackExchange.using("mathjaxEditing", function () {
    StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
    StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
    });
    });
    }, "mathjax-editing");

    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "196"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f121924%2fregular-expression-matching-with-string-slice-in-go%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    3












    $begingroup$

    You're not making good use of regular expressions. A single regex can do the job:



    pattern := regexp.MustCompile(`([a-zA-Z]+)=`)


    The parentheses (...) are the capture the interesting part for you.



    You can use result = pattern.FindAllStringSubmatch(s) to match a string against the regex pattern. The return value is a string, where in each string slice, the 1st element is the entire matched string, and the 2nd, 3rd, ... elements have the content of the capture groups. In this example we have one capture group (...), so the value of the key will be in item[1] of each string slice.



    Instead of a map[string]string map for seen, a map[string]boolean would be more efficient.



    Putting it together:



    func GetKeys(logs string) string {
    var keys string
    pattern := regexp.MustCompile(`([a-zA-Z]+)=`)

    seen := make(map[string]bool)
    for _, log := range(logs) {
    result := pattern.FindAllStringSubmatch(log, -1)
    for _, item := range result {
    key := item[1]
    if _, ok := seen[key]; !ok {
    keys = append(keys, key)
    seen[key] = true
    }
    }
    }

    return keys
    }


    If the input strings are not guaranteed to be in the right format matching the pattern, then you might want to add a guard statement inside the main for loop, for example:



        if len(result) != 2 {
    continue
    }





    share|improve this answer











    $endgroup$













    • $begingroup$
      I was reading about submatches, but I wasn't entirely sure if that's what I wanted or not because I didn't understand that was for capture groups. That makes a lot of sense. What is more efficient about a boolean over the string?
      $endgroup$
      – mxplusb
      Mar 4 '16 at 20:32












    • $begingroup$
      @mynameismevin the storage of a bool is smaller than a string
      $endgroup$
      – janos
      Mar 6 '16 at 20:53










    • $begingroup$
      The original code used FindAllString to find multiple matches per message, but yours uses FindStringSubmatch which looks to return a single match.
      $endgroup$
      – David Harkness
      Mar 7 '16 at 21:36










    • $begingroup$
      A map[string]struct{} is even more efficient and uses less memory than map[string]bool.
      $endgroup$
      – OneOfOne
      Mar 28 '16 at 8:38










    • $begingroup$
      @OneOfOne really? how? and how would I change the line seen[key] = true to make that work?
      $endgroup$
      – janos
      Mar 28 '16 at 10:13
















    3












    $begingroup$

    You're not making good use of regular expressions. A single regex can do the job:



    pattern := regexp.MustCompile(`([a-zA-Z]+)=`)


    The parentheses (...) are the capture the interesting part for you.



    You can use result = pattern.FindAllStringSubmatch(s) to match a string against the regex pattern. The return value is a string, where in each string slice, the 1st element is the entire matched string, and the 2nd, 3rd, ... elements have the content of the capture groups. In this example we have one capture group (...), so the value of the key will be in item[1] of each string slice.



    Instead of a map[string]string map for seen, a map[string]boolean would be more efficient.



    Putting it together:



    func GetKeys(logs string) string {
    var keys string
    pattern := regexp.MustCompile(`([a-zA-Z]+)=`)

    seen := make(map[string]bool)
    for _, log := range(logs) {
    result := pattern.FindAllStringSubmatch(log, -1)
    for _, item := range result {
    key := item[1]
    if _, ok := seen[key]; !ok {
    keys = append(keys, key)
    seen[key] = true
    }
    }
    }

    return keys
    }


    If the input strings are not guaranteed to be in the right format matching the pattern, then you might want to add a guard statement inside the main for loop, for example:



        if len(result) != 2 {
    continue
    }





    share|improve this answer











    $endgroup$













    • $begingroup$
      I was reading about submatches, but I wasn't entirely sure if that's what I wanted or not because I didn't understand that was for capture groups. That makes a lot of sense. What is more efficient about a boolean over the string?
      $endgroup$
      – mxplusb
      Mar 4 '16 at 20:32












    • $begingroup$
      @mynameismevin the storage of a bool is smaller than a string
      $endgroup$
      – janos
      Mar 6 '16 at 20:53










    • $begingroup$
      The original code used FindAllString to find multiple matches per message, but yours uses FindStringSubmatch which looks to return a single match.
      $endgroup$
      – David Harkness
      Mar 7 '16 at 21:36










    • $begingroup$
      A map[string]struct{} is even more efficient and uses less memory than map[string]bool.
      $endgroup$
      – OneOfOne
      Mar 28 '16 at 8:38










    • $begingroup$
      @OneOfOne really? how? and how would I change the line seen[key] = true to make that work?
      $endgroup$
      – janos
      Mar 28 '16 at 10:13














    3












    3








    3





    $begingroup$

    You're not making good use of regular expressions. A single regex can do the job:



    pattern := regexp.MustCompile(`([a-zA-Z]+)=`)


    The parentheses (...) are the capture the interesting part for you.



    You can use result = pattern.FindAllStringSubmatch(s) to match a string against the regex pattern. The return value is a string, where in each string slice, the 1st element is the entire matched string, and the 2nd, 3rd, ... elements have the content of the capture groups. In this example we have one capture group (...), so the value of the key will be in item[1] of each string slice.



    Instead of a map[string]string map for seen, a map[string]boolean would be more efficient.



    Putting it together:



    func GetKeys(logs string) string {
    var keys string
    pattern := regexp.MustCompile(`([a-zA-Z]+)=`)

    seen := make(map[string]bool)
    for _, log := range(logs) {
    result := pattern.FindAllStringSubmatch(log, -1)
    for _, item := range result {
    key := item[1]
    if _, ok := seen[key]; !ok {
    keys = append(keys, key)
    seen[key] = true
    }
    }
    }

    return keys
    }


    If the input strings are not guaranteed to be in the right format matching the pattern, then you might want to add a guard statement inside the main for loop, for example:



        if len(result) != 2 {
    continue
    }





    share|improve this answer











    $endgroup$



    You're not making good use of regular expressions. A single regex can do the job:



    pattern := regexp.MustCompile(`([a-zA-Z]+)=`)


    The parentheses (...) are the capture the interesting part for you.



    You can use result = pattern.FindAllStringSubmatch(s) to match a string against the regex pattern. The return value is a string, where in each string slice, the 1st element is the entire matched string, and the 2nd, 3rd, ... elements have the content of the capture groups. In this example we have one capture group (...), so the value of the key will be in item[1] of each string slice.



    Instead of a map[string]string map for seen, a map[string]boolean would be more efficient.



    Putting it together:



    func GetKeys(logs string) string {
    var keys string
    pattern := regexp.MustCompile(`([a-zA-Z]+)=`)

    seen := make(map[string]bool)
    for _, log := range(logs) {
    result := pattern.FindAllStringSubmatch(log, -1)
    for _, item := range result {
    key := item[1]
    if _, ok := seen[key]; !ok {
    keys = append(keys, key)
    seen[key] = true
    }
    }
    }

    return keys
    }


    If the input strings are not guaranteed to be in the right format matching the pattern, then you might want to add a guard statement inside the main for loop, for example:



        if len(result) != 2 {
    continue
    }






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Mar 28 '16 at 10:30

























    answered Mar 4 '16 at 20:25









    janosjanos

    97.4k12125350




    97.4k12125350












    • $begingroup$
      I was reading about submatches, but I wasn't entirely sure if that's what I wanted or not because I didn't understand that was for capture groups. That makes a lot of sense. What is more efficient about a boolean over the string?
      $endgroup$
      – mxplusb
      Mar 4 '16 at 20:32












    • $begingroup$
      @mynameismevin the storage of a bool is smaller than a string
      $endgroup$
      – janos
      Mar 6 '16 at 20:53










    • $begingroup$
      The original code used FindAllString to find multiple matches per message, but yours uses FindStringSubmatch which looks to return a single match.
      $endgroup$
      – David Harkness
      Mar 7 '16 at 21:36










    • $begingroup$
      A map[string]struct{} is even more efficient and uses less memory than map[string]bool.
      $endgroup$
      – OneOfOne
      Mar 28 '16 at 8:38










    • $begingroup$
      @OneOfOne really? how? and how would I change the line seen[key] = true to make that work?
      $endgroup$
      – janos
      Mar 28 '16 at 10:13


















    • $begingroup$
      I was reading about submatches, but I wasn't entirely sure if that's what I wanted or not because I didn't understand that was for capture groups. That makes a lot of sense. What is more efficient about a boolean over the string?
      $endgroup$
      – mxplusb
      Mar 4 '16 at 20:32












    • $begingroup$
      @mynameismevin the storage of a bool is smaller than a string
      $endgroup$
      – janos
      Mar 6 '16 at 20:53










    • $begingroup$
      The original code used FindAllString to find multiple matches per message, but yours uses FindStringSubmatch which looks to return a single match.
      $endgroup$
      – David Harkness
      Mar 7 '16 at 21:36










    • $begingroup$
      A map[string]struct{} is even more efficient and uses less memory than map[string]bool.
      $endgroup$
      – OneOfOne
      Mar 28 '16 at 8:38










    • $begingroup$
      @OneOfOne really? how? and how would I change the line seen[key] = true to make that work?
      $endgroup$
      – janos
      Mar 28 '16 at 10:13
















    $begingroup$
    I was reading about submatches, but I wasn't entirely sure if that's what I wanted or not because I didn't understand that was for capture groups. That makes a lot of sense. What is more efficient about a boolean over the string?
    $endgroup$
    – mxplusb
    Mar 4 '16 at 20:32






    $begingroup$
    I was reading about submatches, but I wasn't entirely sure if that's what I wanted or not because I didn't understand that was for capture groups. That makes a lot of sense. What is more efficient about a boolean over the string?
    $endgroup$
    – mxplusb
    Mar 4 '16 at 20:32














    $begingroup$
    @mynameismevin the storage of a bool is smaller than a string
    $endgroup$
    – janos
    Mar 6 '16 at 20:53




    $begingroup$
    @mynameismevin the storage of a bool is smaller than a string
    $endgroup$
    – janos
    Mar 6 '16 at 20:53












    $begingroup$
    The original code used FindAllString to find multiple matches per message, but yours uses FindStringSubmatch which looks to return a single match.
    $endgroup$
    – David Harkness
    Mar 7 '16 at 21:36




    $begingroup$
    The original code used FindAllString to find multiple matches per message, but yours uses FindStringSubmatch which looks to return a single match.
    $endgroup$
    – David Harkness
    Mar 7 '16 at 21:36












    $begingroup$
    A map[string]struct{} is even more efficient and uses less memory than map[string]bool.
    $endgroup$
    – OneOfOne
    Mar 28 '16 at 8:38




    $begingroup$
    A map[string]struct{} is even more efficient and uses less memory than map[string]bool.
    $endgroup$
    – OneOfOne
    Mar 28 '16 at 8:38












    $begingroup$
    @OneOfOne really? how? and how would I change the line seen[key] = true to make that work?
    $endgroup$
    – janos
    Mar 28 '16 at 10:13




    $begingroup$
    @OneOfOne really? how? and how would I change the line seen[key] = true to make that work?
    $endgroup$
    – janos
    Mar 28 '16 at 10:13













    0












    $begingroup$

    I know this is an old question but it popped up in my feed so I figured I'd contribute.



    Out of curiosity, why use a regular expression at all? You could achieve the same thing use standard strings package and keep things simple. Here's a Playground that outputs the same result as your Playground.



    package main

    import (
    "fmt"
    "strings"
    )

    func GetKeys(logs string) string {
    exists := make(map[string]bool)
    keys := make(string, 0)
    for _, log := range logs {
    parts := strings.Split(log, "=")
    if len(parts) >= 1 {
    k := parts[0]
    if !exists[k] {
    keys = append(keys, k)
    exists[k] = true
    }
    }
    }
    return keys
    }

    func main() {
    y := string{"key=value", "msg=payload", "test=yay", "msg=payload"}
    fmt.Println(GetKeys(y))
    }





    share|improve this answer









    $endgroup$


















      0












      $begingroup$

      I know this is an old question but it popped up in my feed so I figured I'd contribute.



      Out of curiosity, why use a regular expression at all? You could achieve the same thing use standard strings package and keep things simple. Here's a Playground that outputs the same result as your Playground.



      package main

      import (
      "fmt"
      "strings"
      )

      func GetKeys(logs string) string {
      exists := make(map[string]bool)
      keys := make(string, 0)
      for _, log := range logs {
      parts := strings.Split(log, "=")
      if len(parts) >= 1 {
      k := parts[0]
      if !exists[k] {
      keys = append(keys, k)
      exists[k] = true
      }
      }
      }
      return keys
      }

      func main() {
      y := string{"key=value", "msg=payload", "test=yay", "msg=payload"}
      fmt.Println(GetKeys(y))
      }





      share|improve this answer









      $endgroup$
















        0












        0








        0





        $begingroup$

        I know this is an old question but it popped up in my feed so I figured I'd contribute.



        Out of curiosity, why use a regular expression at all? You could achieve the same thing use standard strings package and keep things simple. Here's a Playground that outputs the same result as your Playground.



        package main

        import (
        "fmt"
        "strings"
        )

        func GetKeys(logs string) string {
        exists := make(map[string]bool)
        keys := make(string, 0)
        for _, log := range logs {
        parts := strings.Split(log, "=")
        if len(parts) >= 1 {
        k := parts[0]
        if !exists[k] {
        keys = append(keys, k)
        exists[k] = true
        }
        }
        }
        return keys
        }

        func main() {
        y := string{"key=value", "msg=payload", "test=yay", "msg=payload"}
        fmt.Println(GetKeys(y))
        }





        share|improve this answer









        $endgroup$



        I know this is an old question but it popped up in my feed so I figured I'd contribute.



        Out of curiosity, why use a regular expression at all? You could achieve the same thing use standard strings package and keep things simple. Here's a Playground that outputs the same result as your Playground.



        package main

        import (
        "fmt"
        "strings"
        )

        func GetKeys(logs string) string {
        exists := make(map[string]bool)
        keys := make(string, 0)
        for _, log := range logs {
        parts := strings.Split(log, "=")
        if len(parts) >= 1 {
        k := parts[0]
        if !exists[k] {
        keys = append(keys, k)
        exists[k] = true
        }
        }
        }
        return keys
        }

        func main() {
        y := string{"key=value", "msg=payload", "test=yay", "msg=payload"}
        fmt.Println(GetKeys(y))
        }






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 26 mins ago









        LansanaLansana

        227211




        227211






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Code Review Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            Use MathJax to format equations. MathJax reference.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f121924%2fregular-expression-matching-with-string-slice-in-go%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Список кардиналов, возведённых папой римским Каликстом III

            Deduzione

            Mysql.sock missing - “Can't connect to local MySQL server through socket”