2015-02-23 18 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(`\* \* \*`) 

這些原始字符串完全忽略轉義序列。