阅读 68

Golang Regex:替换所有符合正则表达式的字符串

概述

Golangregexp包提供了一个名为ReplaceAllString的方法,给定一个字符串,可以用来替换该字符串中符合正则表达式的所有子串。

golang.org/pkg/regexp/…

下面是该方法的签名

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美元捕获年龄

  • 00**或**{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 方法。

golang.org/pkg/regexp/…

在这个方法中,替换的字符串被直接替换,没有任何分析,即它是按字面意思使用的。请看下面的例子

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 上。

文章分类
后端
文章标签