去正则表达式:匹配三个星号

时间:2015-02-23 13:55:18

标签: go

所以我这样做了:

r, _ := regexp.Compile("* * *")
r2 := r.ReplaceAll(b, []byte("<hr>"))

得到了:

panic: runtime error: invalid memory address or nil pointer dereference

所以我想我必须逃脱它们:

r, _ := regexp.Compile("\* \* \*")

但得到了unknown escape secuence

我是初学者。我做错了什么?

3 个答案:

答案 0 :(得分:4)

尝试转义“*”(因为“*”是re2 syntax中用于重复的特殊字符)

r, err := regexp.Compile(`\* \* \*`)
// and yes, always check the error
// or at least use regexp.MustCompile() if you want to fail fast

请注意string literal使用后引号``。

答案 1 :(得分:4)

您没有检查错误。

regexp.Compile为您提供了两个结果:

  1. 已编译的模式(或nil
  2. 编译模式时的错误(或nil
  3. 您忽略了错误并访问了nil结果。观察(on play):

    r, err := regexp.Compile("* * *")
    
    fmt.Println("r:", r)
    fmt.Println("err:", err)
    

    运行此代码会告诉您,确实存在错误。错误是:

      

    错误解析regexp:缺少重复运算符的参数:*

    所以是的,你是对的,你必须逃避重复运算符*。您尝试了以下方法:

    r, err := regexp.Compile("\* \* \*")
    

    因此,编译器出现以下错误:

      

    未知转义序列:*

    由于您的键盘上没有特殊字符,但是有许多转义序列,如\n\r,但是想要在字符串中,编译器会尝试插入这些字符。 \*不是有效的转义序列,因此编译器无法进行替换。你想要做的是逃避转义序列,以便正则表达式解析器能够做到这一点。

    所以,正确的代码是:

    r, err := regexp.Compile("\\* \\* \\*")
    

    处理这些怪癖的最简单方法是使用原始字符串文字(&#34;``&#34;)而不是正常引号:

    r, err := regexp.Compile(`\* \* \*`)
    

    这些原始字符串完全忽略转义序列。

答案 2 :(得分:4)

添加到@ VonC的答案,regexp并不总是答案,通常比使用strings.*慢。

对于复杂的表达式,确定regexp很棒,但是如果你只是想匹配一个字符串然后替换它,那么strings.Replacer是可行的方法:

var asterisksReplacer = strings.NewReplacer(`* * *`, `<hr>`)

func main() {
    fmt.Println(asterisksReplacer.Replace(`xxx * * * yyy *-*-* zzz* * *`))
}

playground