5

次のおもちゃの例を考えてみましょう。名前がasingle で区切られた一連の文字である正規表現と Go で一致させたいので、有効ですが、#そうではありません。次の 2 つの方法で正規表現をコーディングできます。a#a#aaaa#a##a

r1 := regexp.MustCompile(`^a+(#a+)*$`)
r2 := regexp.MustCompile(`^(a+#)*a+$`)

これらの両方が機能します。ここで、単一のスラッシュで区切られた一連の名前を照合する、より複雑なタスクを考えてみましょう。上記のように、次の 2 つの方法でコーディングできます。

^N+(/N+)*$
^(N+/)*N+$

ここで、N は ^ と $ を取り除いた名前の正規表現です。N には 2 つのケースがあるため、4 つの正規表現を使用できます。

    ^a+(#a+)*(/a+(#a+)*)*$
    ^(a+#)*a+(/a+(#a+)*)*$
    ^((a+#)*a+/)*a+(#a+)*$
    ^((a+#)*a+/)*(a+#)*a+$

問題は、文字列と照合すると"aa#a#a/a#a/a"、最初の 1 つが失敗し、残りの 3 つのケースが期待どおりに機能するのはなぜですか? つまり、最初の正規表現が一致しない原因は何ですか? 完全なコードは次のとおりです。

package main

import (
    "fmt"
    "regexp"
)

func main() {
    str := "aa#a#a/a#a/a"
    regs := []string {
        `^a+(#a+)*(/a+(#a+)*)*$`,
        `^(a+#)*a+(/a+(#a+)*)*$`,
        `^((a+#)*a+/)*a+(#a+)*$`,
        `^((a+#)*a+/)*(a+#)*a+$`,
    }    
    for _, r := range(regs) {
        fmt.Println(regexp.MustCompile(r).MatchString(str))
    } 
}

驚くべきことに、それは印刷されますfalse true true true

4

2 に答える 2

0

これは golang 正規表現エンジンのバグに違いありません。より単純なテスト ケースは、動作中^a(/a+(#a+)*)*$に一致しないというものです。 http://play.golang.org/p/CDKxVeXW98を参照してください。a/a#a^(a)(/a+(#a+)*)*$

https://github.com/golang/go/issues/11905に提出しました

于 2015-07-28T07:39:20.250 に答える