信用卡正则表达式无法正常工作

Creditcard regex is not working in flutter

我想确定是哪张信用卡?并相应地渲染 Image Widget。但不知何故它不起作用,我不知道如果我错过了什么或者我的方法是错误的

这是代码片段

它总是渲染最后的 else 部分。

我根据数字渲染容器的输入后缀图标部分

VxState.watch(context, on: [HandleInputChanges]);
TextField(
     maxLength: 16,
     decoration: InputDecoration(
          counter: const Offstage(),
          suffixIcon: getCreditCardType(store.moniPay.cardNo) // Here I am rendering image,
     hintText: "Input card number",
     onChanged: (String? value) {
          HandleInputChanges(value.toString(), 'cardno');
      })

这是 getCreditCardType 方法

Widget getCreditCardType(String creditCardNumber) {
  if (RegExp(r"^4[0-9]{12}(?:[0-9]{3})?$").hasMatch(creditCardNumber)) {
    // visa card
    return Container(
        decoration: const BoxDecoration(
      image: DecorationImage(
        image: AssetImage("assets/images/visa.png"),
        fit: BoxFit.contain,
      ),
    ));
  } else if (RegExp(r"^5[1-5][0-9]{14}$").hasMatch(creditCardNumber)) {
    // master card
    return Container(
        decoration: const BoxDecoration(
      image: DecorationImage(
        image: AssetImage("assets/images/master.png"),
        fit: BoxFit.contain,
      ),
    ));
  } else if (RegExp(r"^3[47][0-9]{13}$").hasMatch(creditCardNumber)) {
    // AExpress card
    return Container(
        decoration: const BoxDecoration(
      image: DecorationImage(
        image: AssetImage("assets/images/american-express.png"),
        fit: BoxFit.contain,
      ),
    ));
  } else if (RegExp(r"^3(?:0[0-5]|[68][0-9])[0-9]{11}$")
      .hasMatch(creditCardNumber)) {
    // diner card
    return Container(
        decoration: const BoxDecoration(
      image: DecorationImage(
        image: AssetImage("assets/images/dinners-club.png"),
        fit: BoxFit.contain,
      ),
    ));
  } else if (RegExp(r"^6(?:011|5[0-9]{2})[0-9]{12}$")
      .hasMatch(creditCardNumber)) {
    // discover card
    return Container(
        decoration: const BoxDecoration(
      image: DecorationImage(
        image: AssetImage("assets/images/discover.png"),
        fit: BoxFit.contain,
      ),
    ));
  } else if (RegExp(r"^(?:2131|1800|35\d{3})\d{11}$")
      .hasMatch(creditCardNumber)) {
    // JCB card
    return Container(
        decoration: const BoxDecoration(
      image: DecorationImage(
        image: AssetImage("assets/images/jcb.png"),
        fit: BoxFit.contain,
      ),
    ));
  } else {
    return const Icon(Icons.credit_card);
  }
}

我试过你记下的函数,正则表达式模式似乎只能识别信用卡的 full/complete 格式。所以它是一个“验证正则表达式”而不是“分类正则表达式”。

它无法识别不完整的信用卡号,所以它总是 return 最后的 else 部分。

对于实时验证,您需要确保只有在当前子字符串有效的情况下才能输入每个后续数字。

您可以使用

^5(?:[1-5][0-9]{0,14})?$                   # VISA
^5(?:[1-5][0-9]{0,14})?$                   # MASTER CARD
^3(?:[47][0-9]{0,13})?$                    # AEXPRESS CARD
^3(?:(?:0[0-5]?|[68][0-9]?)[0-9]{0,11})?$  # DINER CARD
^6(?:(?:01{0,2}|5[0-9]{0,2})[0-9]{0,12})?$ # DISCOVER CARD

更新后的代码如下所示:

Widget getCreditCardType(String creditCardNumber) {
  if (RegExp(r"^4[0-9]{0,15}$").hasMatch(creditCardNumber)) {
    // visa card
    return Container(
        decoration: const BoxDecoration(
      image: DecorationImage(
        image: AssetImage("assets/images/visa.png"),
        fit: BoxFit.contain,
      ),
    ));
  } else if (RegExp(r"^5(?:[1-5][0-9]{0,14})?$").hasMatch(creditCardNumber)) {
    // master card
    return Container(
        decoration: const BoxDecoration(
      image: DecorationImage(
        image: AssetImage("assets/images/master.png"),
        fit: BoxFit.contain,
      ),
    ));
  } else if (RegExp(r"^3(?:[47][0-9]{0,13})?$").hasMatch(creditCardNumber)) {
    // AExpress card
    return Container(
        decoration: const BoxDecoration(
      image: DecorationImage(
        image: AssetImage("assets/images/american-express.png"),
        fit: BoxFit.contain,
      ),
    ));
  } else if (RegExp(r"^3(?:(?:0[0-5]?|[68][0-9]?)[0-9]{0,11})?$")
      .hasMatch(creditCardNumber)) {
    // diner card
    return Container(
        decoration: const BoxDecoration(
      image: DecorationImage(
        image: AssetImage("assets/images/dinners-club.png"),
        fit: BoxFit.contain,
      ),
    ));
  } else if (RegExp(r"^6(?:(?:01{0,2}|5[0-9]{0,2})[0-9]{0,12})?$")
      .hasMatch(creditCardNumber)) {
    // discover card
    return Container(
        decoration: const BoxDecoration(
      image: DecorationImage(
        image: AssetImage("assets/images/discover.png"),
        fit: BoxFit.contain,
      ),
    ));
  } else if (RegExp(r"^(?:2(?:1(?:31?)?)?|1(?:80{0,2})?|3(?:5\d{0,3})?)\d{0,11}$")
      .hasMatch(creditCardNumber)) {
    // JCB card
    return Container(
        decoration: const BoxDecoration(
      image: DecorationImage(
        image: AssetImage("assets/images/jcb.png"),
        fit: BoxFit.contain,
      ),
    ));
  } else {
    return const Icon(Icons.credit_card);
  }
}