我想翻译一下:
{% img <right> /images/testing %}
进入这个:
{{< figure <class="right"> src="/images/testing" >}}
在Golang中使用正则表达式。源字符串中<>
中的部分是可选的。
我有这个代码,当主要测试用例存在时,第一个捕获组存在(&#34; 正确&#34;):
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\" >}}
如果可选组为空,我希望其他文字(&#34; class = &#34;)消失了吗?
答案 0 :(得分:0)
Go regexp不支持条件语句,Replace
系列regexp函数也不支持。
解决方法取决于您拥有的特殊情况的数量。
如果您只有一个案例,我建议您只进行两次更换:首先用属性集替换所有出现的事件,然后替换没有属性(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
,将模式的每个匹配项替换为函数值的输出。然后,此功能可以决定是否包含特定格式。