比较Go中的字符串

dea*_*mon 6 string printf go string-comparison

我正在尝试在字符串中找到命名捕获组的开头以创建一个简单的解析器(请参阅相关问题).为此,该extract函数会记住last4变量中最后一个字符.如果最后4个字符等于"(?P <",则它是捕获组的开头:

package main

import "fmt"

const sample string = `/(?P<country>m((a|b).+)(x|y)n)/(?P<city>.+)`

func main() {
    extract(sample)
}

func extract(regex string) {
    last4 := new([4]int32)
    for _, c := range regex {
        last4[0], last4[1], last4[2], last4[3] = last4[1], last4[2], last4[3], c
        last4String := fmt.Sprintf("%c%c%c%c\n", last4[0], last4[1], last4[2], last4[3])
        if last4String == "(?P<" {
            fmt.Print("start of capturing group")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

http://play.golang.org/p/pqA-wCuvux

但这段代码什么都没打印!last4String == "(?P<"永远不会是真的,虽然如果我last4String在循环中打印,这个子句会出现在输出中.如何比较Go中的字符串呢?

是否有更优雅的方式将int32数组转换为字符串fmt.Sprintf("%c%c%c%c\n", last4[0], last4[1], last4[2], last4[3])

还有什么比这更好的了吗?我的代码对我来说看起来有点不合适.

zzz*_*zzz 3

如果不是为了自学或类似目的,您可能希望使用标准库中现有的RE 解析器,然后“遍历”AST 来执行所需的操作。

func Parse(s string, flags Flags) (*Regexp, error)
Run Code Online (Sandbox Code Playgroud)

Parse 解析正则表达式字符串 s,由指定的 Flags 控制,并返回正则表达式解析树。语法在 regexp 包的顶级注释中进行了描述。

甚至还有一个帮手可以帮助您完成任务。

EDIT1:您的代码已修复:

package main

import "fmt"

const sample string = `/(?P<country>m((a|b).+)(x|y)n)/(?P<city>.+)`

func main() {
        extract(sample)
}

func extract(regex string) {
        var last4 [4]int32
        for _, c := range regex {
                last4[0], last4[1], last4[2], last4[3] = last4[1], last4[2], last4[3], c
                last4String := fmt.Sprintf("%c%c%c%c", last4[0], last4[1], last4[2], last4[3])
                if last4String == "(?P<" {
                    fmt.Println("start of capturing group")
                }
        }
}
Run Code Online (Sandbox Code Playgroud)

(也在这里

EDIT2:您重写的代码:

package main

import (
        "fmt"
        "strings"
)

const sample string = `/(?P<country>m((a|b).+)(x|y)n)/(?P<city>.+)`

func main() {
        extract(sample)
}

func extract(regex string) {
        start := 0
        for {
                i := strings.Index(regex[start:], "(?P<")
                if i < 0 {
                        break
                }

                fmt.Printf("start of capturing group @ %d\n", start+i)
                start += i + 1
        }
}
Run Code Online (Sandbox Code Playgroud)

(也在这里