Jay
Jay

Reputation: 20136

How do you match character OR end of string in a golang regexp?

I am having trouble working out (in golang), within a regular expression, how to match a character, separator, or end of string. The following does almost what I want:

url := "test20160101"
if i, _ := regexp.MatchString("[-a-zA-Z/]20[012]\\d[01]\\d[0123]\\d[-a-zA-Z/]", url); i == true {
    t := regexp.MustCompile("[-a-zA-Z/](20[012]\\d[01]\\d[0123]\\d)[-a-zA-Z/]").FindStringSubmatch(url)[1]
    fmt.Println("match: ", t)
}

https://play.golang.org/p/eWZ_DiOVBl

But I want to also match the following:

url := "test-20160101-"
url := "/20160101/page.html"

I notice there is a \z in the golang documentation however that doesn't work, at least when I put it inside [-a-zA-Z/] i.e. [-a-zA-Z\\z/]

Upvotes: 0

Views: 7414

Answers (2)

Zan Lynx
Zan Lynx

Reputation: 54325

I was interested and played around with it just for fun. Maybe something like this: https://play.golang.org/p/GRVnHTwW0g

package main

import (
    "fmt"
    "regexp"
)

func main() {

    // Want to match "test-20160101", "/20160101/" and "test-20160101"

    re := regexp.MustCompile(`[-a-zA-Z/](20[012]\d[01]\d[0123]\d)([-a-zA-Z/]|\z)`)
    urls := []string{
        "test-20160101",
        "/20160101/page.html",
        "test20160101",
        "nomatch",
        "test19990101",
    }

    for _, url := range urls {
        t := re.FindStringSubmatch(url)
        if len(t) > 2 {
            fmt.Println("match", url, "=", t[1])
        }
    }
}

Upvotes: 2

Andy Schweig
Andy Schweig

Reputation: 6749

Put a ? at the end of the pattern. That means the preceding item is optional.

If you want to anchor the pattern to match at the end of the string, put a $ (or \z) at the very end (after the ?).

Also, you should use backquotes instead of double quotes around your RE. That way you don't have to escape the backslashes.

And as @Zan Lynx mentioned, only compile the RE once.

Upvotes: 3

Related Questions