如何更换使用正则表达式和Golang

问题描述:

可选组我试图把这种:如何更换使用正则表达式和Golang

{% img <right> /images/testing %} 

到这一点。源字符串中<>中的部分是可选的。

我有这样的代码,这似乎是在主试的情况下,当第一个捕获组存在(“”)工作:但是

regexp.MustCompile(`{%\s*img\s*(\p{L}*)\s+([/\S]+)\s+%}`) 
.ReplaceAllString("{% img right /images/testing %}", "{{< figure class=\"$1\" src=\"$2\" >}}") 

如果可选组已丢失,我得到:

{{< figure class="" src="/images/testing" >}} 

这不是我所需要的 - 我想整个class=""部分消失了,就像这样:

{{< figure src="/images/testing" >}} 

这可能吗?我可以替换字符串在某种程度上表明:

{{< figure class=\"$1\" src=\"$2\" >}} 

我想要的附加文本(“类=”)了,如果可选的组是空的?

+0

我不知道,如果条件语句在'go'支持,但他们将要走的路。另请参阅http://*.com/questions/6804586/how-to-conditional-regex –

+0

这似乎并不支持Go正则表达式,不幸的是。感谢您的提示,但! –

+0

你将不得不添加一个自定义函数,到template.funcmap() https://golang.org/pkg/text/template/#FuncMap 然后你的模板调用你的自定义函数做正则表达式和将数据返回给模板,在解析模板之前也调用funcmap,否则会引发错误。在这里看到更多的例子http://technosophos.com/2013/11/23/using-custom-template-functions-in-go.html – reticentroot

转到正则表达式不支持条件语句和Replace家庭的正则表达式功能,不任。 这个问题的解决取决于你有特殊的病例数。

如果你只有一个情况下,我会建议只是做两遍置换:一是更换属性集中所有出现,则更换所有的例无属性(on play):

txt := `{% img right /images/testing %}\n{% img /images/testing %}` 

// without attribute 
txt = regexp.MustCompile(`{%\s*img\s*([/\S]+)\s+%}`). 
    ReplaceAllString(txt, "{{< figure src=\"$1\" >}}") 

// with attribute 
txt = regexp.MustCompile(`{%\s*img\s*(\p{L}*)\s+([/\S]+)\s+%}`). 
    ReplaceAllString(txt, "{{< figure class=\"$1\" src=\"$2\" >}}") 

如果你说这是低效我说:也许,是的。如果你想要的东西更有效(即一些不遍历源字符串两次),那么你就必须建立更多的东西类似于其决定在检测到使用哪种格式的时间解析器。这方面的一个草图会是这样的(on play):

src := []byte("ok" + "{% img right /images/testing %}" + "this" + 
       "{% img /images/testing %}" + "no?") 
dst := bytes.NewBufferString("") 
cidx := 0 

for _, match := range p.FindAllSubmatchIndex(src, -1) { 
    dst.Write(src[cidx:match[0]]) 
    dst.WriteString(newFormat(src, src[match[2]:match[3]], src[match[4]:match[5]])) 
    cidx = match[1] 
} 
dst.Write(src[cidx:]) 

在这个例子中,你从你的源文本src所有内容复制到缓冲区dst,与价值的输出免去您模式的每一个发生一个函数。这个功能可以决定是否包含特定的格式。

+0

这两个有用的建议,谢谢! –