为了账号安全,请及时绑定邮箱和手机立即绑定

Go - 正则表达式内循环

Go - 正则表达式内循环

Go
当年话下 2023-03-07 17:28:07
我有一个包含 600 个正则表达式模式列表的文件,大多数执行这些模式是为了找到网站的特定 ID。例子:regex/www\.effectiveperformanceformat\.com/5regex/bam-cell\.nr-data\.net/5regex/advgoogle\.com/5regex/googleapi\.club/5regex/doubleclickbygoogle\.com/5regex/googlerank\.info/5regex/google-pr7\.de/5regex/usemarketings\.com/5regex/google-rank\.org/5regex/googleanalytcs\.com/5regex/xml\.trafficmoose\.com/5regex/265\.com/5regex/app-measurement\.com/5regex/loftsbaacad\.com/5regex/toldmeflex\.com/5regex/r\.baresi\.xyz/5regex/molodgytot\.biz/5regex/ec\.walkme\.com/5regex/px\.ads\.linkedin\.com/5regex/hinisanex\.biz/5regex/buysellads\.com/5regex/buysellads\.net/5regex/servedby-buysellads\.com/5regex/carbonads\.(net|com)/5regex/oulddev\.biz/5regex/click\.hoolig\.app/5regex/engine\.blacraft\.com/5regex/mc\.yandex\.ru/5regex/ads\.gaming1\.com/5regex/adform\.net/5regex/luzulabeguile\.com/5regex/ficanportio\.biz/5regex/hidelen\.com/5regex/earchmess\.fun/5regex/acrvclk\.com/5regex/track\.wg-aff\.com/5regex/thumb\.tapecontent\.net/5regex/betgorebysson\.club/5regex/in-page-push\.com/5regex/itphanpytor\.club/5regex/mktoresp\.com/5regex/xid\.i-mobile\.co\.jp/5regex/ads\.tremorhub\.com/5到目前为止,我正在使用的是这样的for _, line := range file {l := linedata := strings.Split(l, "/")if data[0] == "regex" {                match, _ := regexp.MatchString(``+data[1]+``, website)                if match {                    id, _ = strconv.Atoi(data[2])                }            }}这是有效的,但我想知道是否有更优化的方法来做到这一点。因为,如果网站与顶部的正则表达式匹配,那就太好了,但如果不匹配,我需要一遍又一遍地循环直到找到它。任何人都可以帮我改进这个吗?
查看完整描述

1 回答

?
jeck猫

TA贡献1909条经验 获得超7个赞

为了减少缓存正则表达式的时间。


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方法负责正则表达式缓存。它将加载具有相对索引的地图中的所有正则表达式(它也会加载测试数据,仅用于基准测试)。


然后你有2个方法:


Precomputed: 使用缓存正则表达式的映射

NonPrecomputed:您的代码段的复制->粘贴

如您所见,该NonPrecomputed方法能够执行 63 次,而Precomputed能够执行 10000 次。如您所见,当方法没有分配时(由于初始缓存),NonPrecomputed方法分配了 ~67 MBPrecomputed


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


查看完整回答
反对 回复 2023-03-07
  • 1 回答
  • 0 关注
  • 135 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号