我正在尝试创建一个简单的命令行日期输入函数。
在 golang 中使用正则表达式模式匹配时,我遇到了一个奇怪的行为:正确的模式 mach 返回 false,但弄乱了我的循环,而不正确的模式只返回 false。这是产生错误的函数:
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\n", &value)
if value == "" {
break // empty value is ok for input
}
fmt.Printf("validid %v\n", validID.MatchString(value))
if validID.MatchString(value) {
break
} else {
fmt.Printf("invalid entry, try again..\n")
}
}
return
}
当我运行它时,我得到以下信息:
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:
注意具有正确模式的最后一个条目如何通过无限循环再运行两次然后停止。知道为什么会发生这种情况吗?
Go 版本 1.2 Linux/386
最佳答案
问题是 Scanf
在读取整行之前返回。我修改了您的代码以使用 bufio.Scanner
和 os.Stdin
,它现在可以工作了:
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'\n", value)
if value == "" {
break // empty value is ok for input
}
fmt.Printf("validid %v\n", validID.MatchString(value))
if validID.MatchString(value) {
break
} else {
fmt.Printf("invalid entry, try again..\n")
}
fmt.Printf("%s - e.g. 2014 Jan 01: ", fieldname)
}
return
}
func main() {
fmt.Println("Returned ", ReadDate("foo"))
}
关于正则表达式匹配对我来说很奇怪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21829546/