Golang正则表达式与Grep性能对比

Golang正则表达式与Grep性能对比 我正在尝试使用regexp包来解析字典"british-english"(Linux系统上的/usr/share/dict/british-english),但我的代码似乎没有正确匹配。当我使用模式 ^cat$ 时,我得到一个空切片,而egrep返回 cat。我使用了ReadString('\')Read()两种方法来从文件中读取数据,但没有区别。以下是完整代码:

func main() {
    fmt.Println("hello world")
}
4 回复

非常感谢!

更多关于Golang正则表达式与Grep性能对比的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


附注:如果你使用 ioutil.ReadFile 一次性读取整个文件内容,而不是逐行读取,可以让程序运行得更快一些。

你需要设置多行标志,否则cat$只会匹配以cat结尾的整个文本。

查看这个示例:https://play.golang.org/p/f-0sdcrnBxA

func main() {
    fmt.Println("hello world")
}

在Go中使用正则表达式匹配时,需要注意正则表达式引擎的行为差异。^cat$ 模式要求精确匹配整行内容为 “cat”,但字典文件可能包含行尾字符或特殊格式。以下是修正后的代码示例:

package main

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

func main() {
    file, err := os.Open("/usr/share/dict/british-english")
    if err != nil {
        log.Fatal(err)
    }
    defer file.Close()

    // 编译正则表达式,启用多行模式
    re := regexp.MustCompile(`(?m)^cat$`)
    
    var matches []string
    scanner := bufio.NewScanner(file)
    for scanner.Scan() {
        line := scanner.Text()
        if re.MatchString(line) {
            matches = append(matches, line)
        }
    }

    if err := scanner.Err(); err != nil {
        log.Fatal(err)
    }

    fmt.Printf("找到 %d 个匹配: %v\n", len(matches), matches)
}

关键修改:

  1. 使用 (?m) 标志启用多行模式,使 ^$ 匹配每行的开始和结束
  2. 使用 bufio.Scanner 逐行读取,自动处理行尾字符
  3. 通过 Text() 方法获取清理后的行内容

如果仍然无法匹配,检查字典文件的实际格式:

// 调试代码:显示前几行内容
file, _ := os.Open("/usr/share/dict/british-english")
scanner := bufio.NewScanner(file)
for i := 0; i < 5 && scanner.Scan(); i++ {
    fmt.Printf("Line %d: %q\n", i, scanner.Text())
}
file.Close()

性能对比方面,Go的regexp包通常比grep慢,因为它是纯Go实现且支持更复杂的正则特性。对于简单模式匹配,考虑使用字符串函数:

// 更快的替代方案
if strings.TrimSpace(line) == "cat" {
    matches = append(matches, line)
}
回到顶部