You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Go协程结合正则表达式解析文本文件中的URL

解决方案:用Go协程+WaitGroup拆分文本搜索URL

先给你重构后的完整代码,解决文本拆分、协程任务分配和结果汇总的问题:

import (
    "fmt"
    "os"
    "regexp"
    "sync"
    "strings"
)

// worker函数:处理分配的文本块,提取URL并写入结果(带锁保证线程安全)
func worker(textBlock string, re *regexp.Regexp, results *[]string, mu *sync.Mutex, wg *sync.WaitGroup) {
    defer wg.Done()

    // 提取当前文本块中的所有https链接
    urls := re.FindAllString(textBlock, -1)
    if len(urls) == 0 {
        return
    }

    // 加锁写入结果,避免并发写入冲突
    mu.Lock()
    *results = append(*results, urls...)
    mu.Unlock()
}

func main() {
    // 1. 一次性读取文件内容,避免每个协程重复IO
    filePath := "repitations"
    b, err := os.ReadFile(filePath)
    if err != nil {
        fmt.Printf("读取文件失败: %v\n", err)
        return
    }
    content := string(b)

    // 2. 拆分文本块:按换行拆分成行切片,避免截断URL
    textBlocks := strings.Split(content, "\n")
    workerCount := 3 // 自定义worker数量
    blockCount := len(textBlocks)
    if blockCount == 0 {
        fmt.Println("文件内容为空")
        return
    }

    // 3. 初始化正则:只匹配https://开头的链接
    re := regexp.MustCompile(`https://\S+`)

    // 4. 初始化结果容器和互斥锁(保证并发安全)
    var results []string
    var mu sync.Mutex
    var wg sync.WaitGroup

    // 5. 分配任务给worker:按平均分配的方式拆分文本块
    blocksPerWorker := (blockCount + workerCount - 1) / workerCount // 向上取整
    for i := 0; i < workerCount; i++ {
        start := i * blocksPerWorker
        end := start + blocksPerWorker
        if end > blockCount {
            end = blockCount
        }
        // 取出当前worker要处理的文本块,合并成字符串
        block := strings.Join(textBlocks[start:end], "\n")
        
        wg.Add(1)
        go worker(block, re, &results, &mu, &wg)
    }

    // 等待所有worker完成
    wg.Wait()

    // 输出汇总结果
    fmt.Println("找到的所有https链接:")
    for _, url := range results {
        fmt.Println("-", url)
    }
    fmt.Printf("总计找到%d个链接\n", len(results))
}

关键改进点说明:

  • 避免重复IO:只在main函数中读一次文件,所有worker共享内容,减少磁盘开销
  • 合理文本拆分:按换行拆分文本,防止把一个完整的URL拆成两半,保证提取准确性
  • 通用worker函数:不用写多个重复的Parser函数,通过参数传递任务,复用逻辑
  • 线程安全的结果收集:用sync.Mutex保护结果切片,避免协程并发写入时的竞态问题
  • 灵活的worker数量:可以自定义workerCount,根据文本大小调整协程数量
  • 精准正则:调整正则为只匹配https://开头的链接,符合需求

如果需要更精确的URL匹配(比如支持带端口、路径的标准URL格式),可以把正则改成更严谨的版本,比如:

re := regexp.MustCompile(`https://(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b(?:[-a-zA-Z0-9()@:%_\+.~#?&//=]*)`)

内容的提问来源于stack exchange,提问作者Raptorik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 05:50:42