Heim  >  Artikel  >  Backend-Entwicklung  >  Golang regexp MatchString() ist nicht idempotent

Golang regexp MatchString() ist nicht idempotent

WBOY
WBOYnach vorne
2024-02-05 23:18:041168Durchsuche

Golang regexp MatchString() 不是幂等的

问题内容

我不知道发生了什么。使用golang的regexp库时,相同的函数相同的输入返回不同的结果。

package main

import (
    "fmt"
    "regexp"
)

type paymentnetworkdata struct {
    regex string
    name  string
}

var payment_networks = map[string]paymentnetworkdata{
    "mastercard": {
        regex: "^5[1-5][0-9]{14}|^(222[1-9]|22[3-9]\\d|2[3-6]\\d{2}|27[0-1]\\d|2720)[0-9]{12}$",
        name:  "mastercard",
    },
    "visamaster": {
        regex: "^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14})$",
        name:  "visamaster",
    },
}

func resolvepaymentnetwork(cardin string) string {
    paynet := "unknown"
    for _, v := range payment_networks {
        regex := regexp.mustcompile(v.regex)

        if regex.matchstring(cardin) {
            paynet = v.name
        }
    }
    return paynet
}

func main() {

    in := "5103901404433835"

    for i := 1; i < 100; i++ {
        paynet := resolvepaymentnetwork(in)
        fmt.println("payment network is: ", paynet)
    }
}

输入:5103901404433835

正则表达式:

mastercard: ^5[1-5][0-9]{14}|^(222[1-9]|22[3-9]\\d|2[3-6]\\d{2}|27[0-1]\\d|2720)[0-9]{12}$
visamaster: ^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14})$

go 语言输出:

payment network is:  visamaster
payment network is:  mastercard
payment network is:  mastercard
payment network is:  visamaster
payment network is:  visamaster
payment network is:  visamaster
payment network is:  visamaster
payment network is:  visamaster
payment network is:  visamaster

我使用 nodejs 测试了相同的代码,在本例中结果始终相同。

js 输出:

Payment Network is:  VisaMaster
Payment Network is:  VisaMaster
Payment Network is:  VisaMaster
Payment Network is:  VisaMaster
Payment Network is:  VisaMaster
Payment Network is:  VisaMaster
Payment Network is:  VisaMaster
Payment Network is:  VisaMaster
Payment Network is:  VisaMaster
Payment Network is:  VisaMaster
  • go 代码演示:https://go.dev/play/p/up4g0jowlv_l
  • js 代码演示:https://playcode.io/1450178

正确答案


您的代码有几个问题:

  1. 没有明显原因使用 map
  2. 两个正则表达式都与提供的卡号匹配。

这些问题,以及通过映射迭代不能保证产生相同序列的事实,导致函数非幂等。

这是更正后的代码:

package main

import (
    "fmt"
    "regexp"
)

type PaymentNetworkData struct {
    Regex *regexp.Regexp
    Name  string
}

var PAYMENT_NETWORKS = [2]PaymentNetworkData{
    {
        Regex: regexp.MustCompile("^(?:5[1-5][0-9]{14}|(?:222[1-9]|22[3-9]\\d|2[3-6]\\d{2}|27[0-1]\\d|2720)[0-9]{12})$"),
        Name:  "Mastercard",
    },
    {
        Regex: regexp.MustCompile("^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14})$"),
        Name:  "VisaMaster",
    },
}

func resolvePaymentNetwork(cardIn string) string {
    for _, v := range PAYMENT_NETWORKS {
        if v.Regex.MatchString(cardIn) {
            return v.Name
        }
    }
    return "Unknown"
}

func main() {
    in := "5103901404433835"

    for i := 1; i < 100; i++ {
        payNet := resolvePaymentNetwork(in)
        fmt.Println("Payment Network is: ", payNet)
    }
}

它使用数组而不是映射来保证顺序。

此外,我还更改了您的结构,使其仅编译一次正则表达式。

每次输出payment network为:mastercard

演示此处

注意,它仍然使用相同的正则表达式(由 评论中的@wiktorstribiżew)。它们看起来不太好,尤其是这部分 (?:4[0-9]{12}(?:[0-9]{3})? - 它也会匹配 13 位数字。
您最好检查卡号的预期格式,并相应地更正表达式。

Das obige ist der detaillierte Inhalt vonGolang regexp MatchString() ist nicht idempotent. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen