前面有學過簡單字串處理了,但是有一些比較複雜的規則要處理怎麼辦,通常其他語言我們會用正則表達式來處理,這章就來看看怎麼使用 Go 的正則表達式吧!
先來看看 Go by Example 上的範例
package main
import "bytes"
import "fmt"
import "regexp"
func main() {
match, \_ := regexp.MatchString("p([a-z]+)ch", "peach")
fmt.Println(match)
r, \_ := regexp.Compile("p([a-z]+)ch")
fmt.Println(r.MatchString("peach"))
fmt.Println(r.FindString("peach punch"))
fmt.Println(r.FindStringIndex("peach punch"))
fmt.Println(r.FindStringSubmatch("peach punch"))
fmt.Println(r.FindStringSubmatchIndex("peach punch"))
fmt.Println(r.FindAllString("peach punch pinch", -1))
fmt.Println(r.FindAllStringSubmatchIndex("peach punch pinch", -1))
fmt.Println(r.FindAllString("peach punch pinch", 2))
fmt.Println(r.Match([]byte("peach")))
r = regexp.MustCompile("p([a-z]+)ch")
fmt.Println(r)
fmt.Println(r.ReplaceAllString("a peach", "<fruit>"))
in := []byte("a peach")
out := r.ReplaceAllFunc(in, bytes.ToUpper)
fmt.Println(string(out))
}
我們來一個一個說明
match, \_ := regexp.MatchString("p([a-z]+)ch", "peach")
fmt.Println(match)
首先我們要先引入 regexp 這個函式庫,然後使用 MatchString 方法來比對字串是否符合規則,結果是回傳佈林值,所以這邊印出 match 會是 true,你應該會注意到有個佔位符 _ ,那是因為我們這邊不需要錯誤的資料所以省略囉。
r, \_ := regexp.Compile("p([a-z]+)ch")
這一句用 Compile 來將規則編譯起來,讓後續的動作可以使用,不需要每次都重新使用 compile。
fmt.Println(r.MatchString("peach"))
這邊會返回 true ,因為跟剛剛一樣都是符合規則的。
fmt.Println(r.FindString("peach punch"))
使用 FindString 來驗證字串是否符合規則,並且回傳,這邊會回傳 peach。
fmt.Println(r.FindStringIndex("peach punch"))
使用 FindStringIndex 跟上面的 FindString 類似,但是他回傳的是他符合規則的是哪到哪,這個例子會回傳 [0 5]
fmt.Println(r.FindStringSubmatch("peach punch"))
FindStringSubmatch 這一句就很不同囉,因為我們的規則有用 [ ],所以這邊會回傳 [ ] 的部份,結果回傳 [peach ea]
fmt.Println(r.FindStringSubmatchIndex("peach punch"))
這是上一個函式 FindStringSubmatch 的延伸,他會回傳他的 Index 位置,回傳 [0 5 1 3]
fmt.Println(r.FindAllString("peach punch pinch", -1))
FindAllString 會比對所有的字串,第二的參數是表示返回的數量,因為比對有的字串可能會是多個,這邊用 -1 表示所有的都要回傳,另外只要第二個參數小於 0 都會回傳全部
fmt.Println(r.FindAllStringSubmatchIndex("peach punch pinch", -1))
FindAllStringSubmatchIndex 用法與上面的雷同,他會回傳所有符合的字串的 Index 位置
fmt.Println(r.FindAllString("peach punch pinch", 2))
如上面解釋過得,這邊就只會回傳兩個,雖然正確的結果有三個。
fmt.Println(r.Match([]byte("peach")))
除了前面的 MatchString 的方法之外,我們也可以用 Match 方法直接把字串轉成 byte 比對喔!
r = regexp.MustCompile("p([a-z]+)ch")
fmt.Println(r)
如果你不喜歡 Compile 會回傳兩個值,你也可以用 MustCompile 來編譯規則
fmt.Println(r.ReplaceAllString("a peach", "<fruit>"))
利用 ReplaceAllString 這個方法可以將符合的字串替換掉
in := []byte("a peach")
out := r.ReplaceAllFunc(in, bytes.ToUpper)
fmt.Println(string(out))
利用 ReplaceAllFunc 方法可以將符合規則的字串丟給函式來處理
這邊簡單的講解了一些 Regular Expression 的用法,詳細的可以參考 http://golang.org/pkg/regexp/