網頁

2022/12/20

Golang 正則表示式 regexp not start with 無作用

今天用Go的正則regexp以表示式^(?ab)\w+$想找出不以特定字串(e.g. "ab")為開頭的字串但沒作用。


例如下面檢查"123"是否滿足不以"ab"開頭,原本認為應該返回true,但卻返回false。regexp.MatchString返回false的原因是因為第二個回傳參數有error但被忽略錯誤所以一直很迷惑。

main.go

package main

import (
    "fmt"
    "regexp"
)

func main() {
    str := "123"
    matched, _ := regexp.MatchString("^(?!ab)", str) // if str not start with 'ab' then match
    fmt.Println(matched)                             // expected true, but false
}

用JavaScript的RegExp明明沒問題。

JavaScript

re = new RegExp("^(?!ab)") // not start with 'ab' then match

console.log(re.test('abc')) // false, 'abc' start with 'ab', not match
console.log(re.test('123')) // true

上網查才知道Go的正則引擎是用RE2,而RE2不支援"lookaround"(lookahead, lookbehind)的語法,正向或負向都不支援,即「前面是」((?=)、「前面不是」((?!)、「結尾是」((?<=)、「結尾不是((?<!)」,因此下面regexp.Compile皆發生錯誤。

main.go

package main

import (
    "fmt"
    "regexp"
)

func main() {
    _, err := regexp.Compile("^(?=ab)") // start with 'ab'
    if err != nil {
        fmt.Println(err) // error parsing regexp: invalid or unsupported Perl syntax: `(?=`
    }

    _, err = regexp.Compile("(?<=ab)$") // end with 'ab'
    if err != nil {
        fmt.Println(err) // error parsing regexp: invalid or unsupported Perl syntax: `(?<`
    }
}

除了以上還有蠻多原本regex的語法都不支援,參考RE2 Syntax

沒有留言:

張貼留言