2015-02-23 84 views
2

所以我这样做:转到正则表达式:匹配三个星号

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

我是一个Go Beginn呃。我究竟做错了什么?

回答

3

添加到@ VonC的答案,正则表达式并不总是答案,并且通常比使用strings.*慢。

对于一个复杂的表情,肯定正则表达式是真棒,但是如果你只是想匹配的字符串和替换它,然后,strings.Replacer是要走的路:

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

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

playground

3

尝试逃脱你的“*”(因为“*”是在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

我会使用['regexp.MustCompile'](http://golang.org/pkg/regexp/#MustCompile),这样regexp错误很早就被发现了。 – OneOfOne 2015-02-23 14:16:35

4

您不检查错误。

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

  1. 编译模式(或nil
  2. 在编译模式错误(或nil

被您忽略的错误和访问nil结果。观察(on play):

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

fmt.Println("r:", r) 
fmt.Println("err:", err) 

运行这段代码,会告诉你,的确有错误。错误是:

错误解析正则表达式:缺少参数重复操作符:*

所以,是的,你说得对,你有逃脱的重复操作*。你试过如下:

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

啥都你从编译器以下错误:由于有许多转义序列像\n *

未知的转义序列或者\r表示在键盘上没有的特殊字符,但想要在字符串中存在,编译器会尝试插入这些字符。 \*不是有效的转义序列,因此编译器无法进行替换。你想要做的是逃避转义序列,以便正则表达式解析器可以做到这一点。

所以,正确的代码是:

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

使用原始字符串字面处理这些类型的怪癖的最简单的方法(“``”),而不是正常报价:

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

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