2016-07-23 67 views
2

在閱讀this post後,我知道我需要使用反引號(`)來包裝我的正則表達式模式。現在我有正則表達式/^(?=^.{8,}$)(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*\s)[[email protected]#$%^&*()]*$/來檢查密碼模式是否正確。我已經用PHP測試過它,它工作正常。但它在Go中不起作用。爲什麼?正則表達式檢查PHP的passwork工作,但不工作去

順便說一句,反引號(`)變量的類型是什麼?它似乎不是string類型。我怎樣才能聲明這個變量容器?

測試代碼

package main 

import(
    "fmt" 
    "regexp" 
) 

func main(){ 
    re := regexp.MustCompile(`/^(?=^.{8,}$)(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*\s)[[email protected]#$%^&*()]*$/`) 
    fmt.Println(re.MatchString("aSfd46Fgwaq")) 
} 

測試結果

Running... 

panic: regexp: Compile(`/^(?=^.{8,}$)(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*\s)[[email protected]#$%^&*()]*$/`): error parsing regexp: invalid or unsupported Perl syntax: `(?=` 

goroutine 1 [running]: 
panic(0x4efae0, 0xc82000a340) 
    /usr/local/go/src/runtime/panic.go:481 +0x3e6 
regexp.MustCompile(0x576140, 0x4b, 0x100000000) 
    /usr/local/go/src/regexp/regexp.go:232 +0x16f 
main.main() 
    /home/casper/.local/share/data/liteide/goplay.go:9 +0x30 
exit status 2 

Error: process exited with code 1. 

謝謝!

+4

轉到正則表達式不支持lookarounds和正則表達式的分隔符。 –

+0

是否有任何其他插件,我可以'從github'獲取'用於這個正則表達式模式? – Casper

+0

'(?!。* \ s)'lookahead是冗餘的,因爲消費模式不匹配空格。 –

回答

4

Go regexp不支持週轉。此外,/.../正則表達式分隔符也不受支持(在Go中有特殊的方法來表示這些分隔符)。

您既可以使用轉到一個環視,支持正則表達式庫(here is a PCRE-supporting one)或分割的條件和使用的幾個小的,可讀的正則表達式:

package main 

import (
    "fmt" 
    "regexp" 
    "unicode/utf8" 
) 

func main() { 
    s := "aSfd46Fgwaq" 
    lower_cond := regexp.MustCompile(`[a-z]`) 
    upper_cond := regexp.MustCompile(`[A-Z]`) 
    digit_cond := regexp.MustCompile(`[0-9]`) 
    whole_cond := regexp.MustCompile(`^[[email protected]#$%^&*()]*$`) 
    pass_len := utf8.RuneCountInString(s) 
    fmt.Println(lower_cond.MatchString(s) && upper_cond.MatchString(s) && digit_cond.MatchString(s) && whole_cond.MatchString(s) && pass_len >= 8) 
} 

Go playground demo

注:我在使用utf8.RuneCountInString該演示確保UTF8字符串長度正確解析。否則,您可能會使用len(s)來計算應該滿足ASCII輸入的字節數。

更新

如果表現不盡如人意,您可以考慮使用一個簡單的非正則表達式的方法:

package main 

import "fmt" 

func main() { 
    myString := "aSfd46Fgwaq" 
    has_digit := false 
    has_upper := false 
    has_lower := false 
    pass_length := len(myString) 
    for _, value := range myString { 
     switch { 
     case value >= '0' && value <= '9': 
      has_digit = true 
     case value >= 'A' && value <= 'Z': 
      has_upper = true 
     case value >= 'a' && value <= 'z': 
      has_lower = true 
     } 
    } 
    fmt.Println(has_digit && has_upper && has_lower && pass_length >= 8) 

} 

another Go demo

+0

如果我使用標準的lib函數來驗​​證字符串輸入,它會比使用regexp方法更快嗎?regexp方法似乎需要花時間來解碼正則表達式模式。您會推薦什麼? – Casper