关闭
duanqiang5722 2016-07-23 07:59
浏览 103
已采纳

用于密码检查的PHP正则表达式模式在Go中不起作用

After reading this post, I know I need to use a backquotes ( ` ) to wrap my regex pattern. Now I have regex pattern /^(?=^.{8,}$)(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*\s)[0-9a-zA-Z!@#$%^&*()]*$/ to check password pattern whether is correct. I have tested it with PHP and it work correctly. But it does not work in Go. Why?

By the way, what is the type of backquoted ( ` ) variable? it seems not string type. How can I declare this variable container?

Testing Code

package main

import(
    "fmt"
    "regexp"
)

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

Testing Result

Running...

panic: regexp: Compile(`/^(?=^.{8,}$)(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?!.*\s)[0-9a-zA-Z!@#$%^&*()]*$/`): 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.

Thank you!

展开全部

  • 写回答

1条回答 默认 最新

  • douguan1887 2016-07-23 10:50
    关注

    Go regexp does not support lookarounds. Also, the /.../ regex delimiters are not supported, either (there are special methods in Go to express those).

    You may either use a lookaround-supporting regex library for Go (here is a PCRE-supporting one) or split the conditions and use several small, readable regexps:

    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(`^[0-9a-zA-Z!@#$%^&*()]*$`)
        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)
    }
    

    See Go playground demo

    NOTE: I used utf8.RuneCountInString in the demo to make sure even UTF8 string length is parsed correctly. Otherwise, you might use len(s) that will count bytes that should suffice for ASCII input.

    Update

    If the performance is not satisfactory, you may consider using a simpler non-regex approach:

    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)
    
    }
    

    See another Go demo

    展开全部

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
编辑
预览

报告相同问题?

手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部