3

I am using package regexp to find all mactch substring in Golang, but get unexpected result.Here is my code:

package main

import (
    "fmt"
    "regexp"
)

func main() {
    str := "build: xxxxxx Prefix:middle#6\nPrefix:middle#16026Prefix:middle#1111\n Prefix:middle#110 Prefix:middle.#2 Prefix:middl.e#111 Prefix:middle#112"
    regexpStr := "\\bPrefix:([a-zA-Z0-9]+[\\w-.]+[^.])#[0-9]+"
    re := regexp.MustCompile(regexpStr)
    matchs := re.FindAllString(str, -1)
    fmt.Println(matchs)
}

You can see it in https://go.dev/play/p/XFSMW09MKxV.

expected:

[Prefix:middle#6 Prefix:middle#110 Prefix:middl.e#111 Prefix:middle#112]

But I got:

[Prefix:middle#6 Prefix:middle#16026 Prefix:middle#110 Prefix:middl.e#111 Prefix:middle#112]

Why Prefix:middle#16026 macthed? Could someone tell me the reason? And how to fix it, thx.

Here is the rules for what should match:

I want to extract Prefix:${middle}#${number} in a String.

  • ${middle} rules:

    • Allowed characters: letters, numbers, underscores, underscores, dots
    • Must begin with a letter or number
    • Can't end with a dot
  • ${number} rules:

    • Shoule be number
  • Prefix:${middle}#${number} can appear at the beginning or end of a string, or in the middle of a string, but:

    • Appear at the beginning of the string, it needs to be followed by a space or /n;
    • Appear at the end of the string, it needs to be preceded by a space or /n;
    • in the middle of the string, but it needs to be preceded and followed by a newline symbol or a space.
4
  • Why woudn’t Prefix:middle#16026 match? Commented Sep 16, 2022 at 8:44
  • What I expect is that [Prefix:middle#6 Prefix:middle#110 Prefix:middl.e#111 Prefix:middle#112],How can I fix it? What kind of regexpStr should I use?@Biffen Commented Sep 16, 2022 at 8:47
  • Could you explain the rules (in English if not in regex) for what should match? The current pattern matches Prefix:middle#16026 and I can’t see a reason, or even an intention, for why it shouldn’t. Commented Sep 16, 2022 at 8:49
  • @Biffen I update the question to add the rules. Cound you pls read it? Commented Sep 16, 2022 at 9:15

1 Answer 1

2

You can use the following regex with regexp.FindAllStringSubmatch:

(?:\s|^)(Prefix:[a-zA-Z0-9][\w.-]*[^.]#\d+)(?:\s|$)

See the regex demo.

Note that this pattern will only work after doubling whitespaces in the string because both the whitespace boundaries, (?:\s|^) and (?:\s|$), are consuming patterns, and will prevent getting consecutive matches. Hence, regexp.MustCompile(\s).ReplaceAllString(str, "$0$0") or similar should be used before running the above regex.

Details:

  • (?:\s|^) - either a whitespace or start of string
  • (Prefix:[a-zA-Z0-9][\w.-]*[^.]#\d+) - Group 1:
    • Prefix: - a fixed string
    • [a-zA-Z0-9] - an alphanumeric
    • [\w.-]* - zero or more letters, digits, underscores, dots or hyphens
    • [^.] - a char other than .
    • # - a # char
    • \d+ - one or more digits
  • (?:\s|$) - either a whitespace or end of string

See the Go demo:

package main

import (
    "fmt"
    "regexp"
)

func main() {
    str := "Prefix:middle#113 build: xxxxxx Prefix:middle#6\nPrefix:middle#16026Prefix:middle#1111\n Prefix:middle#110 Prefix:middle.#2 Prefix:middl.e#111 Prefix:middle#112"
    re := regexp.MustCompile(`(?:\s|^)(Prefix:[a-zA-Z0-9][\w.-]*[^.]#\d+)(?:\s|$)`)
    matchs := re.FindAllStringSubmatch(regexp.MustCompile(`\s`).ReplaceAllString(str, "$0$0"), -1)
    for _, m := range matchs {
        fmt.Println(m[1])
    }
}

Output:

Prefix:middle#113
Prefix:middle#6
Prefix:middle#110
Prefix:middl.e#111
Prefix:middle#112
Sign up to request clarification or add additional context in comments.

12 Comments

Thx for response quickly! I update the question to add the rules. Cound you pls read it again?
@spike014 What does not work? What do you expect?
I comment in the end of the code, go.dev/play/p/lPZAjMyGIHH
@spike014 See the update.
@spike014 See this Go demo, does it work as expected?
|

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.