I have a string that could have a -name followed by value (that can have spaces) and there could also be -descr after that followed by a value (the -descr followed by value may nor may not be there):
Example strings:
runcmd -name abcd xyz -descr abc def
or
runcmd -name abcd xyz
With Go language, how do I write regexp, that returns me the string before -descr if it exists. so, for both examples above, the result should be:
runcmd -name abcd xyz
I was trying:
regexp.MustCompile(`(-name ).+?=-descr`)
But, that did not return any match. I wanted to know the correct regexp to get the string up until -descr if it exists
You could capturin first part with -name
in a group, then match what is in between and use an optional second capturing group to match -descr
and what follows.
Then you could use the capturing groups when creating the desired result.
^(.*? -name\b).*?(-descr\b.*)?$
For example:
s := "runcmd -name abcd xyz -descr abc def"
re1 := regexp.MustCompile(`^(.*? -name\b).*?(-descr\b.*)?$`)
result := re1.FindStringSubmatch(s)
fmt.Printf(result[1] + "..." + result[2])
Result:
runcmd -name...-descr abc def
By "Does not work", do you mean it doesn't match anything, or just not what you expect?
https://regex101.com/ is generally very helpful when testing regular expressions.
I do not believe there's a simple way to achieve what you want. Things become a lot simpler if we can assume the text betweeen -name
and -descr
doesn't contain any -
in which case, regex.MustCompile(`-name ([^-]*)`)
should work
With this kind of thing, often it's easier and clearer to use 2 regular expressions. So the first strips -descr
and anything following it, and the first matches -name
and all subsequent characters.
You are not dealing with a regular language here, so there is no reason to bust out the (slow) regexp engine. The strings package is quite enough:
package main
import (
"fmt"
"strings"
"unicode"
)
func main() {
fmt.Printf("%q
", f("runcmd -name abcd xyz -descr abc def"))
fmt.Printf("%q
", f("runcmd -name abcd xyz"))
fmt.Printf("%q
", f("-descr abc def"))
}
func f(s string) string {
if n := strings.Index(s, "-descr"); n >= 0 {
return strings.TrimRightFunc(s[:n], unicode.IsSpace)
}
return s
}
// Output:
// "runcmd -name abcd xyz"
// "runcmd -name abcd xyz"
// ""
Try it on the playground: https://play.golang.org/p/RFC65CYe6mp