-1

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

8
  • When you say something "does not work", it's important to explain how - error, incorrect behavior (and specify what), etc. Just from looking at the code, however, your regex is looking for a string with an = in it, but you exemplars do not contain that character. Commented Jan 9, 2019 at 16:24
  • If you can use a capturing group, try ^(.*? -name.*?)(?: *-descr|$) demo Commented Jan 9, 2019 at 16:27
  • Should -descr be there? Because it is not in the second example. Commented Jan 9, 2019 at 16:30
  • @Thefourthbird, will this capturing group work with Golang? Can you tell the syntax to use with regex.MustCompile? Commented Jan 9, 2019 at 16:31
  • 2
    Why use a regex for such a simple task? Commented Jan 9, 2019 at 16:54

3 Answers 3

1

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
Sign up to request clarification or add additional context in comments.

11 Comments

Is it possible to modify this so the first group only contains uptil -name? The reason is, I would eventually need to do something like re1.ReplaceAllString(s, "$1"+"...."+" ")), so I can return the original string just with the value of -name replaced with ...., so the output string becomes runcmd -name .... -descr abc def which is the final goal
@user1892775 To get only the first group you could use ^(.*? -name) demo. In that case you could also use just a match instead ^.*? -name demo and it could look like this Go demo
Not sure, if I was clear enough, I want to modify the regexp so that s := "runcmd -name abcd xyz -descr abc def" re1 := regexp.MustCompile(regexp) fmt.Println(re1.ReplaceAllString(s, "$1"+"...."+" ")) should be `runcmd -name .... -descr abc def'
If you could share an example which would give that output (the string with value for -name replaced with ....) as indicated in the code above, that would really help
@user1892775 Do you mean like this using 2 capturing groups? ideone.com/vOTdLz
|
0

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.

1 Comment

Text betweeen -name and -descr doesn't contain any -
0

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\n", f("runcmd -name abcd xyz -descr abc def"))
    fmt.Printf("%q\n", f("runcmd -name abcd xyz"))
    fmt.Printf("%q\n", 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

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.