昨天有同事在看k8s源码,突然问了一个看似很简单的问题,https://golang.org/pkg/regexp/#Regexp.ReplaceAllString 官方文档中ReplaceAllString的解释,到底是什么意思?到底怎么用?
官方英文原文:
func (re *Regexp) ReplaceAllString(src, repl string) string
| 1 | 
 | 
中文文档:
| 1 | ReplaceAllLiteral返回src的一个拷贝,将src中所有re的匹配结果都替换为repl。在替换时,repl中的'$'符号会按照Expand方法的规则进行解释和替换,例如$1会被替换为第一个分组匹配结果。 | 
看上去一脸懵逼,还是不理解这个函数到底怎么用。
又去看官方的示例:
| 1 | Example: | 
第一个替换勉强能看明白,是用T去替换-ab-axxb-中符合正则表达式匹配的部分;第二个中的$是什么意思?$1看起来像是匹配正则表达式分组中第一部分,那$1W呢?${1}W呢?带着这些问题,开始深入研究这个函数到底怎么用。
首先,$符号在Expand函数中有解释过:
| 1 | func (re *Regexp) Expand(dst []byte, template []byte, src []byte, match []int) []byte | 
说了这么多,其实最终要的部分可以概括为三点:
- $后面只有数字,则代表正则表达式的分组索引,关于正则表达式的分组解释:
捕获组可以通过从左到右计算其开括号来编号 。例如,在表达式 (A)(B(C)) 中,存在四个这样的组:
| 0 | (A)(B(C)) | 
|---|---|
| 1 | (A) | 
| 2 | (B(C)) | 
| 3 | (C) | 
组零始终代表整个表达式
之所以这样命名捕获组是因为在匹配中,保存了与这些组匹配的输入序列的每个子序列。捕获的子序列稍后可以通过 Back 引用(反向引用) 在表达式中使用,也可以在匹配操作完成后从匹配器检索。
匹配正则表达式的$1部分,保留该部分,去掉其余部分;
- $后面是字符串,即- $name,代表匹配对应(?P- …)语法产生的命名捕获分组的名字 
- ${数字}字符串,即- ${1}xxx,意思是匹配正则表达式的分组1,- src中匹配分组1的保留,并删除- src剩余部分,追加- xxx,后面会有代码示例解释这部分,也是最难理解的部分
- 最简单的情况,参数repl是字符串,将src中所有re的匹配结果都替换为repl
下面用代码来解释以上几种情况:
| 1 | package main | 
上面代码输出依次是:
| 1 | go run main.go | 
总结
Goregexp包中的ReplaceAllString设计有些许反人类,理解和使用上感觉不方便,如果你有更好的理解或者示例代码,Call me!
 
     
        