概述
Golangregexp包提供了一个名为ReplaceAllString的方法,给定一个字符串,可以用来替换该字符串中符合正则表达式的所有子串。
下面是该方法的签名
func (re *Regexp) ReplaceAllString(src, repl string) string
它接受两个参数
-
第一个是输入字符串
-
第二个是替换字符串。
ReplaceAll返回src字符串的副本,用替换字符串repl替换与Regexp匹配的字符串,替换
字符串可以是
-
一个字面字符串
-
具有捕获组未命名子匹配的字符串。
-
具有捕获组命名子匹配的字符串
听起来很混乱?当我们看到所有的例子时,一切都会清楚。让我们看看这些例子
替换字符串是一个字面字符串
在这种情况下,替换字符串是一个字面字符串。下面是一个同样的例子。
package main
import (
"fmt"
"regexp"
)
func main() {
sampleRegexp := regexp.MustCompile(`\w+:[0-9]\d{1,3}`)
input := "The persons are John:21, Simon:23, and Mike:19"
result := sampleRegexp.ReplaceAllString(input, "redacted")
fmt.Println(string(result))
}
输出
The persons are redacted, redacted, and redacted
在上面的例子中,我们有以下的词条
`\w+:[0-9]\d{1,3}`
它匹配的名字和年龄对的形式是
name:age
然后我们有下面的输入字符串,其中有三个名字**:年龄**对
The persons are John:21, Simon:23, Mike:19
我们通过用redacted关键字替换所有的name:age对来进行编辑。
result := sampleRegexp.ReplaceAllString(input, "redacted")
注意,替换字符串是一个字面字符串,即
redacted
一个具有捕获组未命名子匹配的字符串
这就是我们在词组中拥有捕获组的情况。要了解关于捕获组的细节,请参考这篇文章。
在替换字符串中
-
1美元或**${1}**代表第一个子匹配。
-
2美元或**${2}**代表第二个子匹配项
-
...以此类推
让我们看看下面的例子,就会更清楚了
package main
import (
"fmt"
"regexp"
)
func main() {
sampleRegexp := regexp.MustCompile(`(\w+):([0-9]\d{1,3})`)
input := "The names are John:21, Simon:23, and Mike:19"
result := sampleRegexp.ReplaceAllString(input, "$2:$1")
fmt.Println(string(result))
}
输出
The names are 21:John, 23:Simon, and 19:Mike
在上面的例子中,我们有如下的词条
(\w+):([0-9]\d{1,3})
它和上面一样匹配姓名和年龄对,但是它有两个捕获组(用圆括号括起来),其中1美元捕获姓名,2美元捕获年龄
- {0}- 全部匹配
(\w+):([0-9]\d{1,3})
- 1美元或**${1}** --第一个子匹配
(\w+)
- 2美元或${2}--第二个子匹配项
([0-9]\d{1,3})
然后,我们有以下的输入字符串,其中有三个名字**:年龄**对
The names are John:21, Simon:23, and Mike:19
然后在替换的字符串中,我们把年龄放在第一位,然后是名字。
result := sampleRegexp.ReplaceAllString(input, "$2:$1")
这就是为什么在输出中,我们先有年龄,后有名字。
The names are 21:John, 23:Simon, and 19:Mike
你也可以只替换其中一个子匹配。例如,如果你只想删减年龄,也可以这样做。请看下面的程序
package main
import (
"fmt"
"regexp"
)
func main() {
sampleRegexp := regexp.MustCompile(`(\w+):([0-9]\d{1,3})`)
input := "The names are John:21, Simon:23, and Mike:19"
result := sampleRegexp.ReplaceAllString(input, "$1")
fmt.Println(string(result))
}
输出
The names are John, Simon, and Mike
在上面的代码中,替换字符串是
$1
所以它用唯一的名字替换了整个name:age对。
你也可以使用**$0**,它将代表整个匹配。
package main
import (
"fmt"
"regexp"
)
func main() {
sampleRegexp := regexp.MustCompile(`(\w+):([0-9]\d{1,3})`)
input := "The names are John:21, Simon:23, and Mike:19"
result := sampleRegexp.ReplaceAllString(input, "-$0-")
fmt.Println(string(result))
}
输出
The names are -John:21-, -Simon:23-, and -Mike:19-
在上面的例子中,我们在$0之前和之后添加了**'-'**。
-$0-
这就是为什么输出结果如上
如果替换的字符串包含字面美元,我们可以使用ReplaceAllLiteralString 方法。
在这个方法中,替换的字符串被直接替换,没有任何分析,即它是按字面意思使用的。请看下面的例子
package main
import (
"fmt"
"regexp"
)
func main() {
sampleRegexp := regexp.MustCompile(`(\w+):([0-9]\d{1,3})`)
input := "The names are John:21, Simon:23, and Mike:19"
result := sampleRegexp.ReplaceAllLiteralString(input, "$1")
fmt.Println(string(result))
}
输出
The names are $1, $1, and $1
正如上面的输出所示,它打印了字面的美元符号。
一个有命名子匹配的捕获组的字符串
这种情况下,我们在regex中命名了捕获组。要了解关于捕获组的细节,请参考这篇文章。
让我们先看一个程序,在这个程序中我们将看到命名的捕获组。之后我们将对这个程序进行剖析,以便更清楚地了解。
package main
import (
"fmt"
"regexp"
)
func main() {
sampleRegexp := regexp.MustCompile(`(?P\w+):(?P[0-9]\d{1,3})`)
input := "The names are John:21, Simon:23, Mike:19"
result := sampleRegexp.ReplaceAllString(input, "$Age:$Name")
fmt.Println(string(result))
}
输出
The names are 21:John, 23:Simon, 19:Mike
在上面的例子中,我们有以下的词条
`(?P\w+):(?P[0-9]\d{1,3})`
它与上面的名字和年龄对相匹配,但它有两个名字捕获组
- 第一个抓取组的名称是**"姓名"**
(?P\w+)
- 第二个捕捉组的名称是**"年龄"**
(?P[0-9]\d{1,3})
然后我们有下面的输入字符串,其中有三个名字**:年龄**对
The names are John:21, Simon:23 and Mike:19
然后在替换字符串中,我们把年龄放在第一位,然后是名字。
result := sampleRegexp.ReplaceAllString(input, "$Age:$Name")
这就是为什么在输出中,我们先有年龄,后有名字。
The names are 21:John, 23:Simon, 19:Mike
这就是关于在golang中替换符合正则表达式的字符串的全部内容。希望你喜欢这篇文章。请在评论中分享反馈。
另外,请查看我们的Golang高级教程系列------。Golang高级教程
帖子Golang Regex:替换所有符合正则表达式的字符串出现在Welcome To Golang By Example 上。