【问题标题】:Golang Regular expression always returns false?Golang正则表达式总是返回false?
【发布时间】:2018-03-19 03:01:09
【问题描述】:

我正在接受用户输入(正则表达式),并检查文件的给定行是否匹配它。然后,如果有匹配项(行的 ID),我会返回一些 ID,仅此而已。但是,它显示为我的match 总是返回false?但是,有趣的是,如果我抛出一个通配符.*,程序的执行时间将比特定的正则表达式长得多。那么,一定有什么事情发生了——为什么它总是返回 false?

示例代码:

func main() {

    // User input from command line
    reader := bufio.NewReader(os.Stdin)
    fmt.Print("Enter regexp: ")
    userRegexp, _ := reader.ReadString('\n')

    // List all .html files in static dir
    files, err := filepath.Glob("static/*.html")
    if err != nil {
        log.Fatal(err)
    }

    // Empty array of int64's to be returned with matching results
    var lineIdArr []int64

    for _, file := range files {
        htmlFile, _ := os.Open(file)
        fscanner := bufio.NewScanner(htmlFile)

        // Loop over each line
        for fscanner.Scan() {

            line := fscanner.Text()

            match := matchLineByValue(userRegexp, line) // This is always false?

            // ID is always the first item. Seperate by ":" and cast it to int64.
            lineIdStr := line[:strings.IndexByte(line, ':')]
            lineIdInt, err := strconv.ParseInt(lineIdStr, 10, 64)

            if err != nil {
                panic(err)
            }

            // If matched, append ID to lineIdArr
            if match {
                lineIdArr = append(lineIdArr, lineIdInt)
            }
        }
    }
    fmt.Println("Return array: ", lineIdArr)
    fmt.Println("Using regular expression: ", userRegexp)
}

func matchLineByValue(re string, s string) bool {
    return regexp.MustCompile(re).MatchString(s)
}

regexp.MustCompile(re).MatchString(s) 不是从用户输入构造正则表达式并将其与整行匹配的正确方法吗?

它匹配的字符串相当长(它基本上是一个完整的html文件),这会出现问题吗?

【问题讨论】:

  • 返回 false 的正则表达式甚至可以是 .*,这没有任何意义。示例输入基本上是一个大的 HTML 文件。不过,它有时会用 \n? 转义字符串?这是个问题吗?
  • 编译表达式既昂贵又缓慢。不要为每一行编译相同的表达式;重复使用它。

标签: regex go


【解决方案1】:

调用userRegexp, _ := reader.ReadString('\n') 返回一个带有尾随换行符的字符串。修剪换行符:

 userRegexp, err := reader.ReadString('\n')
 if err != nil {
    // handle error
 }
 userRegexp = userRegexp[:len(userRegexp)-1]

以下是一些其他改进的代码(编译一次正则表达式,使用扫描仪字节):

// User input from command line
reader := bufio.NewReader(os.Stdin)
fmt.Print("Enter regexp: ")
userRegexp, err := reader.ReadString('\n')
if err != nil {
    log.Fatal(err)
}
userRegexp = userRegexp[:len(userRegexp)-1]
re, err := regexp.Compile(userRegexp)
if err != nil {
    log.Fatal(err)
}

// List all .html files in static dir
files, err := filepath.Glob("static/*.html")
if err != nil {
    log.Fatal(err)
}

// Empty array of int64's to be returned with matching results
var lineIdArr []int64

for _, file := range files {
    htmlFile, _ := os.Open(file)
    fscanner := bufio.NewScanner(htmlFile)
    // Loop over each line
    for fscanner.Scan() {
        line := fscanner.Bytes()
        if !re.Match(line) {
            continue
        }
        lineIdStr := line[:bytes.IndexByte(line, ':')]
        lineIdInt, err := strconv.ParseInt(string(lineIdStr), 10, 64)
        if err != nil {
            log.Fatal(err)
        }
        lineIdArr = append(lineIdArr, lineIdInt)
    }
}
fmt.Println("Return array: ", lineIdArr)
fmt.Println("Using regular expression: ", userRegexp)

【讨论】:

    猜你喜欢
    • 2012-05-31
    • 2011-12-13
    • 1970-01-01
    • 2016-07-26
    • 1970-01-01
    • 2015-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多