1. 程式人生 > >二十、Go基礎程式設計:正則表示式

二十、Go基礎程式設計:正則表示式

正則表示式是一種進行模式匹配和文字操縱的複雜而又強大的工具。雖然正則表示式比純粹的文字匹配效率低,但是它卻更靈活。按照它的語法規則,隨需構造出的匹配模式就能夠從原始文字中篩選出幾乎任何你想要得到的字元組合。

Go語言通過regexp標準包為正則表示式提供了官方支援,如果你已經使用過其他程式語言提供的正則相關功能,那麼你應該對Go語言版本的不會太陌生,但是它們之間也有一些小的差異,因為Go實現的是RE2標準,除了\C,詳細的語法描述參考:http://code.google.com/p/re2/wiki/Syntax

其實字串處理我們可以使用strings包來進行搜尋(Contains、Index)、替換(Replace)和解析(Split、Join)等操作,但是這些都是簡單的字串操作,他們的搜尋都是大小寫敏感,而且固定的字串,如果我們需要匹配可變的那種就沒辦法實現了,當然如果strings包能解決你的問題,那麼就儘量使用它來解決。因為他們足夠簡單、而且效能和可讀性都會比正則好。

package main

import (
    "fmt"
    "regexp"
)

func main() {
    context1 := "3.14 123123 .68 haha 1.0 abc 6.66 123."

    //MustCompile解析並返回一個正則表示式。如果成功返回,該Regexp就可用於匹配文字。
    //解析失敗時會產生panic
    // \d 匹配數字[0-9],d+ 重複>=1次匹配d,越多越好(優先重複匹配d)
    exp1 := regexp.MustCompile(`\d+\.\d+`)

    //返回保管正則表示式所有不重疊的匹配結果的[]string切片。如果沒有匹配到,會返回nil。
    //result1 := exp1.FindAllString(context1, -1) //[3.14 1.0 6.66]
    result1 := exp1.FindAllStringSubmatch(context1, -1) //[[3.14] [1.0] [6.66]]

    fmt.Printf("%v\n", result1)
    fmt.Printf("\n------------------------------------\n\n")

    context2 := `
        <title>標題</title>
        <div>你過來啊</div>
        <div>hello mike</div>
        <div>你大爺</div>
        <body>呵呵</body>
    `
    //(.*?)被括起來的表示式作為分組
    //匹配<div>xxx</div>模式的所有子串
    exp2 := regexp.MustCompile(`<div>(.*?)</div>`)
    result2 := exp2.FindAllStringSubmatch(context2, -1)

    //[[<div>你過來啊</div> 你過來啊] [<div>hello mike</div> hello mike] [<div>你大爺</div> 你大爺]]
    fmt.Printf("%v\n", result2)
    fmt.Printf("\n------------------------------------\n\n")

    context3 := `
        <title>標題</title>
        <div>你過來啊</div>
        <div>hello 
        mike
        go</div>
        <div>你大爺</div>
        <body>呵呵</body>
    `
    exp3 := regexp.MustCompile(`<div>(.*?)</div>`)
    result3 := exp3.FindAllStringSubmatch(context3, -1)

    //[[<div>你過來啊</div> 你過來啊] [<div>你大爺</div> 你大爺]]
    fmt.Printf("%v\n", result3)
    fmt.Printf("\n------------------------------------\n\n")

    context4 := `
        <title>標題</title>
        <div>你過來啊</div>
        <div>hello 
        mike
        go</div>
        <div>你大爺</div>
        <body>呵呵</body>
    `
    exp4 := regexp.MustCompile(`<div>(?s:(.*?))</div>`)
    result4 := exp4.FindAllStringSubmatch(context4, -1)

    /*
        [[<div>你過來啊</div> 你過來啊] [<div>hello
            mike
            go</div> hello
            mike
            go] [<div>你大爺</div> 你大爺]]
    */
    fmt.Printf("%v\n", result4)
    fmt.Printf("\n------------------------------------\n\n")

    for _, text := range result4 {
        fmt.Println(text[0]) //帶有div
        fmt.Println(text[1]) //不帶帶有div
        fmt.Println("================\n")
    }
}