2016-07-23 93 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