正则表达式匹配对我来说很奇怪

I'm trying to create a simple command line date entry function.

I get a weird behavior when using regexp pattern matching with golang: correct pattern mach returns false but messes with my loop while incorrect pattern just returns false. Here is the function that produces the error:

func ReadDate(fieldname string) (value string) {
    var validID = regexp.MustCompile(`^\d\d\d\d\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dez)\s\d\d$`)
    for {
        value = ""
        fmt.Printf("%s - e.g. 2014 Jan 01: ", fieldname)
        fmt.Scanf("%s
", &value)
        if value == "" {
            break // empty value is ok for input
        }
        fmt.Printf("validid %v
", validID.MatchString(value))
        if validID.MatchString(value) {
            break
        } else {
            fmt.Printf("invalid entry, try again..
")
        }
    }
    return
}

when I run it, I get the following:

date - e.g. 2014 Jan 01: x
validid false
date - e.g. 2014 Jan 01: x
validid false
date - e.g. 2014 Jan 01: 2014 Jan 01
validid false
date - e.g. 2014 Jan 01: validid false
date - e.g. 2014 Jan 01: validid false
date - e.g. 2014 Jan 01: 

Notice how the last entry with the correct pattern runs another two times through the infinite loop and then stops. Any ideas why this might happen?

Go version 1.2 Linux/386

the problem is Scanf returns before the whole line is read. I've modified your code to use bufio.Scanner and os.Stdin, and it works now:

package main

import (
    "bufio"
    "fmt"
    "os"
    "regexp"
)

func ReadDate(fieldname string) (value string) {
    var validID = regexp.MustCompile(`^\d\d\d\d\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dez)\s\d\d$`)
    fmt.Printf("%s - e.g. 2014 Jan 01: ", fieldname)

    scanner := bufio.NewScanner(os.Stdin)
    for scanner.Scan() {
        value = scanner.Text()
        fmt.Printf("Read value: '%s'
", value)
        if value == "" {
            break // empty value is ok for input
        }
        fmt.Printf("validid %v
", validID.MatchString(value))
        if validID.MatchString(value) {
            break
        } else {
            fmt.Printf("invalid entry, try again..
")
        }
        fmt.Printf("%s - e.g. 2014 Jan 01: ", fieldname)

    }
    return
}

func main() {
    fmt.Println("Returned ", ReadDate("foo"))
}