最吸引人的是这
fmt.Println(re.ReplaceAllString("-ab-axxb-","$1W"))条线。该文件说:在repl内部,
$符号解释为Expand
并展开说:
在模板中,变量由
$name或形式的子字符串表示${name},其中name是字母,数字和下划线的非空序列。
对超出范围或不匹配的索引的引用或在正则表达式中不存在的名称将替换为空切片。在
$name形式中,名称应尽可能长:$1x等于${1x},不等于${1}x,并且$10等于${10},不等于${1}0。
因此,在第三更换,
$1W被视为
${1W}由于此群体不被初始化,一个空字符串用于替换。当我说“该组未初始化”时,我的意思是说该组未在正则表达式模式中定义,因此,在 匹配 操作期间未填充该组。 替换
意味着获取所有匹配项,然后将它们替换为替换模式。在 匹配 阶段将填充 反向引用 (
$xx构造)。该模式中缺少该组,因此在 匹配
期间未填充该组,并且在发生 替换 阶段时仅使用一个空字符串。
$1W__
第二个和第四个替换项很容易理解,上面的答案中对此进行了描述。只是
$1反向引用字符 捕获
与所述第一捕获组(封闭具有一对未转义括号的子模式),同样是用实施例4。
您可以认为{}这是 消除 替换模式 歧义 的一种方法。
现在,如果需要使结果一致,请使用 命名捕获
(?P<1W>....):
re := regexp.MustCompile("a(?P<1W>x*)b") // <= See here, pattern updatedfmt.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编号的反向引用指向使用命名捕获捕获的相同文本
$1W。



