我从golang.org website阅读示例代码。本质上,代码如下所示:

re := regexp.MustCompile("a(x*)b")
fmt.Println(re.ReplaceAllString("-ab-axxb-", "T"))
fmt.Println(re.ReplaceAllString("-ab-axxb-", "$1"))
fmt.Println(re.ReplaceAllString("-ab-axxb-", "$1W"))
fmt.Println(re.ReplaceAllString("-ab-axxb-", "${1}W"))

输出如下:
-T-T-
--xx-
---
-W-xxW-

我了解第一个输出,但不了解其余三个。有人可以向我解释结果2,3和4。谢谢。

最佳答案

最吸引人的是fmt.Println(re.ReplaceAllString("-ab-axxb-", "$1W"))行。 docs say:

Expand说:

因此,在第3次替换中,$1W被视为${1W},并且由于未初始化该组,因此将使用空字符串进行替换。
当我说“该组未初始化”时,我的意思是说该组未在正则表达式模式中定义,因此,在匹配操作期间未填充该组。替换意味着获取所有匹配项,然后将它们替换为替换模式。在匹配阶段将填充反向引用($xx构造)。模式中缺少$1W组,因此在匹配期间未填充该组,并且在发生替换阶段时仅使用一个空字符串。
第二个和第四个替换项很容易理解,并在上述答案中进行了描述。只是$1向后引用了第一个捕获组(子模式用一对未转义的括号括起来)捕获的字符,与示例4相同。
您可以考虑使用{}来消除替换模式的歧义。
现在,如果需要使结果一致,请使用名为capture (?P<1W>....):

re := regexp.MustCompile("a(?P<1W>x*)b")  // <= See here, pattern updated
fmt.Println(re.ReplaceAllString("-ab-axxb-", "T"))
fmt.Println(re.ReplaceAllString("-ab-axxb-", "$1"))
fmt.Println(re.ReplaceAllString("-ab-axxb-", "$1W"))
fmt.Println(re.ReplaceAllString("-ab-axxb-", "${1}W"))
结果:
-T-T-
--xx-
--xx-
-W-xxW-
现在,第二行和第三行会产生一致的输出,因为命名的组1W也是第一组,并且$1编号的反向引用指向使用命名的capture $1W捕获的相同文本。

关于regex - 去ReplaceAllString,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34673039/

10-10 05:46