regex Go -正则表达式内部循环

xpszyzbs  于 2022-11-18  发布在  Go
关注(0)|答案(1)|浏览(161)

我有一个文件与600正则表达式模式的列表,大多数被执行,以找到一个特定的id为一个网站。
示例:

regex/www\.effectiveperformanceformat\.com/5
regex/bam-cell\.nr-data\.net/5
regex/advgoogle\.com/5
regex/googleapi\.club/5
regex/doubleclickbygoogle\.com/5
regex/googlerank\.info/5
regex/google-pr7\.de/5
regex/usemarketings\.com/5
regex/google-rank\.org/5
regex/googleanalytcs\.com/5
regex/xml\.trafficmoose\.com/5
regex/265\.com/5
regex/app-measurement\.com/5
regex/loftsbaacad\.com/5
regex/toldmeflex\.com/5
regex/r\.baresi\.xyz/5
regex/molodgytot\.biz/5
regex/ec\.walkme\.com/5
regex/px\.ads\.linkedin\.com/5
regex/hinisanex\.biz/5
regex/buysellads\.com/5
regex/buysellads\.net/5
regex/servedby-buysellads\.com/5
regex/carbonads\.(net|com)/5
regex/oulddev\.biz/5
regex/click\.hoolig\.app/5
regex/engine\.blacraft\.com/5
regex/mc\.yandex\.ru/5
regex/ads\.gaming1\.com/5
regex/adform\.net/5
regex/luzulabeguile\.com/5
regex/ficanportio\.biz/5
regex/hidelen\.com/5
regex/earchmess\.fun/5
regex/acrvclk\.com/5
regex/track\.wg-aff\.com/5
regex/thumb\.tapecontent\.net/5
regex/betgorebysson\.club/5
regex/in-page-push\.com/5
regex/itphanpytor\.club/5
regex/mktoresp\.com/5
regex/xid\.i-mobile\.co\.jp/5
regex/ads\.tremorhub\.com/5

目前我用的是这样的

for _, line := range file {
l := line
data := strings.Split(l, "/")
if data[0] == "regex" {
                match, _ := regexp.MatchString(``+data[1]+``, website)
                if match {
                    id, _ = strconv.Atoi(data[2])
                }
            }
}

这是工作,但我想知道是否有一个更优化的方式来做到这一点。因为,如果网站匹配的regex在顶部,伟大的,但如果不是,我需要intenered循环一遍又一遍,直到找到它。
有人能帮我改进吗?
顺祝商祺

fbcarpbf

fbcarpbf1#

为了减少时间,您可以缓存regexp。

package main

import (
    "bufio"
    "bytes"
    "fmt"
    csvutils "github.com/alessiosavi/GoGPUtils/csv"
    "log"
    "os"
    "regexp"
    "strconv"
    "strings"
    "time"
)

func main() {
    now := time.Now()
    Precomputed("www.google.it")
    fmt.Println(time.Since(now))
    now = time.Now()
    NonPrecomputed("www.google.it")
    fmt.Println(time.Since(now))
}
func NonPrecomputed(website string) int {
    for _, line := range cachedLines {
        l := line
        data := strings.Split(l, "/")
        if data[0] == "regex" {
            match, _ := regexp.MatchString(``+data[1]+``, website)
            if match {
                id, _ := strconv.Atoi(data[2])
                return id
            }
        }
    }

    return -1
}
func Precomputed(site string) int {
    for regex, id := range rawRegex {
        if ok := regex.MatchString(site); ok {
            return id
        }
    }
    return -1
}

var rawRegex map[*regexp.Regexp]int = make(map[*regexp.Regexp]int)
var cachedLines []string
var sites []string

func init() {
    now := time.Now()
    file, err := os.ReadFile("regex.txt")
    if err != nil {
        panic(err)
    }

    scanner := bufio.NewScanner(bytes.NewReader(file))

    for scanner.Scan() {
        txt := scanner.Text()
        cachedLines = append(cachedLines, txt)
        split := strings.Split(txt, "/")
        if len(split) == 3 {
            compile, err := regexp.Compile(split[1])
            if err != nil {
                panic(err)
            }
            if rawRegex[compile], err = strconv.Atoi(split[2]); err != nil {
                panic(err)
            }
        }
    }
    file, err = os.ReadFile("top500Domains.csv")
    if err != nil {
        panic(err)
    }
    _, csvData, err := csvutils.ReadCSV(file, ',')
    if err != nil {
        panic(err)
    }
    for _, line := range csvData {
        sites = append(sites, line[1])
    }
    log.Println("Init took:", time.Since(now))
}

init方法负责regexp缓存。它将加载Map中所有带有相对索引的regexp(它将加载仅用于基准测试的测试数据)。
那么你有2个方法:

  • Precomputed:使用缓存的regexp的Map
  • NonPrecomputed:复制-〉粘贴代码片段

正如您所看到的,NonPrecomputed方法能够执行63次执行,Precomputed能够执行10000次执行。正如您所看到的,NonPrecomputed方法分配了大约67 MB,而Precomputed方法没有分配(由于初始缓存)

C:\opt\SP\Workspace\Go\Temp>go test -bench=. -benchmem -benchtime=10s
2022/11/03 00:45:35 Init took: 10.8397ms
goos: windows
goarch: amd64
pkg: Temp
cpu: 11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz
Benchmark_Precomputed-8            10000           1113887 ns/op               0 B/op          0 allocs/op
Benchmark_NonPrecomputed-8            63         298434740 ns/op        65782238 B/op     484595 allocs/op
PASS
ok      Temp    41.548s

相关问题