regex - 如何用正则表达式和 Golang 替换可选组

标签 regex go

我正在尝试翻译这个:

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

进入这个:

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

在 Golang 中使用正则表达式。 <>中的部分在源字符串中是可选的。

我有这段代码,当第一个捕获组存在时(“right”),它似乎在主测试用例中工作:

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\" >}}

如果可选组为空,我希望附加文本(“class=”)消失?

最佳答案

Go 正则表达式不支持条件语句,正则表达式函数的 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 中,用函数值的输出替换您的模式的每次出现。然后,此函数可以决定是否包含特定格式。

关于regex - 如何用正则表达式和 Golang 替换可选组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43168329/

相关文章:

regex - 正则表达式mirc情况

php - 从 PHP 数组中仅输出括号中不包含 HTML 标记的值

字符串拆分中的 Java 正则表达式量词

go - golang struct中tag有什么用?

go - Cron 作业作为程序或原生 k8s 方式

regex - 如何使用正则表达式匹配 "not followed by some literals"?

Java 通过带问号的换行符正则表达式拆分字符串

go - 如何使用其他结构变量访问不同的结构变量?

go - 单值上下文中的多值 url.Parse() (net/url)

goavro 和原始 Go 数据结构