如何使用Regexp包的ReplaceAll函数在Go中替换字符?

huangapple go评论92阅读模式
英文:

How do you replace a character in Go using the Regexp package ReplaceAll function?

问题

我不熟悉类C语法,并且想要编写代码来查找和替换源字符串中的所有'A'为'B',例如使用Regexp包的ReplaceAll或ReplaceAllString函数。我该如何设置类型Regexp、src和repl?这是来自Go文档的ReplaceAll代码片段:

// ReplaceAll返回src的副本,其中所有与Regexp匹配的内容都被repl替换。不支持在替换文本中使用表达式(例如\1或$1)。
func (re *Regexp) ReplaceAll(src, repl []byte) []byte {
lastMatchEnd := 0; // 最近匹配的结束位置
searchPos := 0; // 下一次查找匹配的位置
buf := new(bytes.Buffer);
for searchPos <= len(src) {
a := re.doExecute("", src, searchPos);
if len(a) == 0 {
break // 没有更多匹配
}

    // 复制此匹配之前的未匹配字符。
    buf.Write(src[lastMatchEnd:a[0]]);

    // 现在插入替换字符串的副本,但不适用于紧接在另一个匹配之后的空字符串的匹配。
    // (否则,对于同时匹配空字符串和非空字符串的模式,我们会得到双重替换。)
    if a[1] > lastMatchEnd || a[0] == 0 {
        buf.Write(repl)
    }
    lastMatchEnd = a[1];

    // 推进到此匹配之后;始终至少推进一个字符。
    _, width := utf8.DecodeRune(src[searchPos:len(src)]);
    if searchPos+width > a[1] {
        searchPos += width
    } else if searchPos+1 > a[1] {
        // 仅在输入字符串的末尾需要此子句。在这种情况下,DecodeRuneInString返回width=0。
        searchPos++
    } else {
        searchPos = a[1]
    }
}

// 复制最后一个匹配之后的未匹配字符。
buf.Write(src[lastMatchEnd:len(src)]);

return buf.Bytes();

}

英文:

I am not familiar with C-like syntaxes and would like to write code to find & replace, say, all 'A's to 'B's in a source string, say 'ABBA' with the Regexp package ReplaceAll or ReplaceAllString functions? How do I set up type Regexp, src and repl? Here's the ReplaceAll code snippet from the Go documentation:

<pre>// ReplaceAll returns a copy of src in which all matches for the Regexp
// have been replaced by repl. No support is provided for expressions
// (e.g. \1 or $1) in the replacement text.
func (re *Regexp) ReplaceAll(src, repl []byte) []byte {
lastMatchEnd := 0; // end position of the most recent match
searchPos := 0; // position where we next look for a match
buf := new(bytes.Buffer);
for searchPos <= len(src) {
a := re.doExecute("", src, searchPos);
if len(a) == 0 {
break // no more matches
}

    // Copy the unmatched characters before this match.
    buf.Write(src[lastMatchEnd:a[0]]);

    // Now insert a copy of the replacement string, but not for a
    // match of the empty string immediately after another match.
    // (Otherwise, we get double replacement for patterns that
    // match both empty and nonempty strings.)
    if a[1] &gt; lastMatchEnd || a[0] == 0 {
        buf.Write(repl)
    }
    lastMatchEnd = a[1];

    // Advance past this match; always advance at least one character.
    _, width := utf8.DecodeRune(src[searchPos:len(src)]);
    if searchPos+width &gt; a[1] {
        searchPos += width
    } else if searchPos+1 &gt; a[1] {
        // This clause is only needed at the end of the input
        // string.  In that case, DecodeRuneInString returns width=0.
        searchPos++
    } else {
        searchPos = a[1]
    }
}

// Copy the unmatched characters after the last match.
buf.Write(src[lastMatchEnd:len(src)]);

return buf.Bytes();

}
<code>

答案1

得分: 4

这是一个执行你想要的操作的例程:

package main
import ("fmt"; "regexp"; "os"; "strings";)
func main () {
    reg, error := regexp.Compile ("B");
    if error != nil {
        fmt.Printf ("编译失败:%s", error.String ());
        os.Exit (1);
    }
    output := string (reg.ReplaceAll (strings.Bytes ("ABBA"),
                                      strings.Bytes ("A")));
    fmt.Println (output);
}
英文:

This is a routine to do what you want:

package main
import (&quot;fmt&quot;; &quot;regexp&quot;; &quot;os&quot;; &quot;strings&quot;;);
func main () {
    reg, error := regexp.Compile (&quot;B&quot;);
    if error != nil {
        fmt.Printf (&quot;Compile failed: %s&quot;, error.String ());
        os.Exit (1);
    }
    output := string (reg.ReplaceAll (strings.Bytes (&quot;ABBA&quot;),
				      strings.Bytes (&quot;A&quot;)));
    fmt.Println (output);
}

答案2

得分: 1

这是一个小例子。你也可以在Regexp测试类中找到好的例子。

package main

import (
	"fmt"
	"regexp"
	"strings"
)

func main() {
	re, _ := regexp.Compile("e")
	input := "hello"
	replacement := "a"
	actual := string(re.ReplaceAll(strings.Bytes(input), strings.Bytes(replacement)))
	fmt.Printf("新模式 %s", actual)
}
英文:

Here is a small example. You can also find good examples in he Regexp test class

package main

import (
	&quot;fmt&quot;
	&quot;regexp&quot;
	&quot;strings&quot;
)

func main() {
	re, _ := regexp.Compile(&quot;e&quot;)
	input := &quot;hello&quot;
	replacement := &quot;a&quot;
	actual := string(re.ReplaceAll(strings.Bytes(input), strings.Bytes(replacement)))
	fmt.Printf(&quot;new pattern %s&quot;, actual)
}

huangapple
  • 本文由 发表于 2009年11月16日 00:42:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/1738057.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定