2016-01-08 117 views
3

我读了golang.org website的示例代码。本质上,代码如下所示:前往ReplaceAllString

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- 

我理解的第一输出,但我不明白的其余3个。有人可以向我解释结果2,3和4.谢谢。

+0

您是否阅读过示例代码上方的文本? – ruakh

+0

是的,我读过。但我仍不明白扩张如何运作。 –

回答

2

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

里面REPL,$迹象解释为Expand

而且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 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- 

第2和第3行现在产生一致的输出,因为指定组1W也是第一组组,$1编号的反向参考点以与命名捕获$1W捕获相同的文本。

+0

“这个组未初始化”是什么意思?如何初始化一个组?对不起,我的问题可能是天真的。 –

+0

该组未在正则表达式模式中指定,因此在匹配操作期间未填充*。替换意味着获得所有匹配,然后用替换模式替换它们。 *反向引用*('$ xx'构造)在*匹配*阶段被填充。 $ 1W'组在模式中缺失,因此它在匹配过程中未被填充,并且在替换阶段发生时仅使用空字符串。 –

+0

如果我需要,应该做些什么来使价值1W的礼物?我正在尝试接受有关指定组的教育。 –

1

$数或$名称是在正则表达式或子组名称子组的索引

fmt.Println(re.ReplaceAllString("-ab-axxb-", "$1")) 

$ 1是正则表达式亚组1 = x*

fmt.Println(re.ReplaceAllString("-ab-axxb-", "$1W")) 

$ 1W无子组名称1W =>全部替换与空

fmt.Println(re.ReplaceAllString("-ab-axxb-", "${1}W")) 

$ 1和$ {1}是相同的。为W

替换所有亚组1的详细资料:https://golang.org/pkg/regexp/

+0

谢谢。你能解释第二个结果吗? –

+0

好的,$名称后的所有字符是名称,所以没有替换键=>替换键= null,如果找不到组名,它将使用默认正则表达式a(x *)b并用空值替换 – trquoccuong

+0

谢谢让我了解这个指定的群体。 –

0

$1${1}

${1}的简写是第一个(1)基团,例如的值第一对()的内容。该组是(x*),即任何数量的x

ReplaceAllString取代每一个匹配。有两场比赛。第一个是ab,第二个是axxb

否2.用组内容替换任何匹配:第一个匹配是“”,第二个匹配是“xx”。

否4.在组内容后添加“W”。

否3.留作练习。提示:第十二个捕获组将是12美元。

+0

因此,我可以理解,替换对每场比赛都是动态的吗? –

+0

谢谢。你的回答帮助我理解了第二个输出。 –

+0

我们不是在写一本数学书籍,而是把东西留作练习。 – snorberhuis