2017-02-28 119 views
1

我發現許多類似的questions不適用於Go regex syntax有沒有一種方法可以匹配除了使用Go.Regexp的常量字符串以外的所有內容?

我試圖匹配的字符串的形式是anything/anything/somestring。使用\/.*\/.*\/(.*)的模式,我將匹配somestring,但我試圖匹配除包含somestring的字符串之外的任何內容。

大多數答案建議使用類似\/.*\/.*\/((?!somestring).*),但是在golang正則表達式中我得到:? The preceding token is not quantifiable

澄清:/test/test/MATCH會產生匹配,而/test/test/somestring不會。這可能與(有限)Go正則表達式語法?

+0

看起來幾乎一切都是_NOT SUPPORTED_。它真的是一個正則表達式引擎嗎?無論如何,斷言不可用(它說),所以'(?!somestring)',這是你所需要的,已經不存在了。唯一的解決方法是在while循環中使用正則表達式'\ /.* \ /.* \ /(。*)'。每個匹配,字符串比較組1與'somestring'。 – sln

+2

RE2(Go實現)不支持lookarounds。只需自己檢查一下submatches。 – JimB

回答

1

anything/anything/somestring不應該表示爲\/.*\/.*\/(.*)。第一個.*與字符串中的最後一個相匹配,但一個/。您需要使用否定字符類[^/](不應該在Go正則表達式中轉義/)。

由於RE2是Go使用不支持向前看符號,你需要捕捉(爲JimB mentions in the comments所有三個部分你有興趣,並檢查捕獲組#1的值之後,決定如何返回:

包主要

import (
    "fmt" 
    "regexp" 
) 

func main() { 
    s := "anything/anything/somestring" 
    r := regexp.MustCompile(`^[^/]+/[^/]+/(.*)`) 
    val := r.FindStringSubmatch(s) 
    // fmt.Println(val[1]) // -> somestring 
    if len(val) > 1 && val[1] != "somestring" { // val has more than 1 element and is not equal to somestring? 
     fmt.Println(val[1])  // Use val[1] 
    } else { 
     fmt.Println("No match") // Else, report no match 
    } 
} 

Go demo

0

Golang故意留下這個功能了,因爲沒有辦法實現它在O(n)的時間,以滿足真正的正則表達式according to Russ Cox的約束:

缺乏普遍斷言,像缺乏的反向引用, 不是關於正則表達式風格的聲明。由於不知道如何有效地實現它們,所以它是 。如果 可以實現它們,同時保留 當前軟件包正則表達式的保證,即它對 輸入進行單次掃描並在O(n)時間內運行,那麼我會很樂意審查並且 同意CL 。但是,我已經思考了如何在五年內完成這個工作,不管什麼時候開始。

看起來最好的方法是在JimB上面提到的手動檢查匹配之後。

相關問題