Golang正则表达式匹配字符串,直到给定的字符序列

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.*)?$

Regex demo | Go demo

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