dragon_9000 2014-02-17 12:47
浏览 16
已采纳

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

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

  • 写回答

1条回答 默认 最新

  • douzhong4222 2014-02-17 13:11
    关注

    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"))
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测
  • ¥15 ETLCloud 处理json多层级问题
  • ¥15 matlab中使用gurobi时报错
  • ¥15 这个主板怎么能扩出一两个sata口
  • ¥15 不是,这到底错哪儿了😭
  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么