问题
我有string
个值的片段,其中每个值都是根据模板格式化的。在我的特定情况下,我正在尝试解析Markdown URL,如下所示:
- [What did I just commit?](#what-did-i-just-commit)
- [I wrote the wrong thing in a commit message](#i-wrote-the-wrong-thing-in-a-commit-message)
- [I committed with the wrong name and email configured](#i-committed-with-the-wrong-name-and-email-configured)
- [I want to remove a file from the previous commit](#i-want-to-remove-a-file-from-the-previous-commit)
- [I want to delete or remove my last commit](#i-want-to-delete-or-remove-my-last-commit)
- [Delete/remove arbitrary commit](#deleteremove-arbitrary-commit)
- [I tried to push my amended commit to a remote, but I got an error message](#i-tried-to-push-my-amended-commit-to-a-remote-but-i-got-an-error-message)
- [I accidentally did a hard reset, and I want my changes back](#i-accidentally-did-a-hard-reset-and-i-want-my-changes-back)
我想做什么?
我正在寻找将其解析为类型值的方法:
type Entity struct {
Statement string
URL string
}
我尝试了什么?
如您所见,所有项目都遵循以下模式:- [{{ .Statement }}]({{ .URL }})
。我尝试使用fmt.Sscanf
函数将每个字符串扫描为:
var statement, url string
fmt.Sscanf(s, "[%s](%s)", &statement, &url)
这导致:
statement = "I"
url = ""
问题在于扫描仪仅存储空格分隔值。我不明白为什么没有根据此规则填充URL字段。
如何获得上述Markdown值?
编辑:正如Marc所建议的那样,我将添加几个澄清点:
答案 0 :(得分:3)
注意:以下解决方案仅适用于"简单",非转义输入降价链接。如果这符合您的需求,请继续使用。要获得完全降价兼容性,您应使用正确的降价解析器,例如gopkg.in/russross/blackfriday.v2。
您可以使用正则表达式从标记链接中获取链接文本和URL。
因此一般输入文本的格式为:
[some text](somelink)
对此进行建模的正则表达式:
\[([^\]]+)\]\(([^)]+)\)
其中:
\[
是文字[
([^\]]+)
适用于"some text"
,除关闭方括号外的所有内容\]
是文字]
\(
是文字(
([^)]+)
适用于"somelink"
,除关闭括号外,其他所有内容\)
是文字)
示例:
r := regexp.MustCompile(`\[([^\]]+)\]\(([^)]+)\)`)
inputs := []string{
"[Some text](#some/link)",
"[What did I just commit?](#what-did-i-just-commit)",
"invalid",
}
for _, input := range inputs {
fmt.Println("Parsing:", input)
allSubmatches := r.FindAllStringSubmatch(input, -1)
if len(allSubmatches) == 0 {
fmt.Println(" No match!")
} else {
parts := allSubmatches[0]
fmt.Println(" Text:", parts[1])
fmt.Println(" URL: ", parts[2])
}
}
输出(在Go Playground上尝试):
Parsing: [Some text](#some/link)
Text: Some text
URL: #some/link
Parsing: [What did I just commit?](#what-did-i-just-commit)
Text: What did I just commit?
URL: #what-did-i-just-commit
Parsing: invalid
No match!
答案 1 :(得分:0)
您可以在此用例的pure-Go代码中创建一个简单的词法分析器。多年前Rob Pike有一个great talk进入text/template的设计,这将适用。实现将一系列状态函数链接到一个整体状态机中,并通过一个通道(通过Goroutine)传递令牌,以便以后处理。