在使用c++11 regex验证车牌号前,要首先明白有几个坑要踩:

1.车牌号校验规则,只有弄清楚了校验车牌号的规则才能写出正确的正则表达式,所以首先要弄清楚车牌号的校验规则。

2.c++11 中regex的用法,其中用到了regex、 regex_match,其中有个坑就是中文的匹配。

一、车牌号校验规则

1.普通常见车牌(蓝牌、黄牌)

车牌号码的长度:7位 , 第一位是省份简称, 第二位是发证机关代码,第二位到第七位是大写英文字符和阿拉伯数字组成。例如:京A88888

java 车牌号正则表达式包含绿牌 车牌号正则表达式匹配_#include

java 车牌号正则表达式包含绿牌 车牌号正则表达式匹配_java 车牌号正则表达式包含绿牌_02

2.最后一位为汉字的车牌。

车牌号码的长度:7位 , 第一位是省份简称, 第二位是发证机关代码,第二位到第六位是大写英文字符和阿拉伯数字组成。最后一个字符为汉字,汉字包括“挂”、“学”、“警”、“港”、“澳”。比如:鲁A8888学

java 车牌号正则表达式包含绿牌 车牌号正则表达式匹配_c++_03

java 车牌号正则表达式包含绿牌 车牌号正则表达式匹配_c++_04

java 车牌号正则表达式包含绿牌 车牌号正则表达式匹配_字符串_05

java 车牌号正则表达式包含绿牌 车牌号正则表达式匹配_java 车牌号正则表达式包含绿牌_06

3.新军车牌

以两位为大写英文字母开头,后面以5位阿拉伯数字组成。如:KA12345。

java 车牌号正则表达式包含绿牌 车牌号正则表达式匹配_c++_07

4.新能源车牌

车牌号码的长度:8位 , 第一位是省份简称, 第二位是发证机关代码,按照现行新能源车牌号码规则:

第三位:1-9DF;

第四位:1-9A-Z,无I、O字母;

第五-七位:0-9;

第八位:1-9DF;

java 车牌号正则表达式包含绿牌 车牌号正则表达式匹配_#include_08


关于第1、2、3种车牌

省份简称:京津晋冀蒙辽吉黑沪苏浙皖闽赣鲁豫鄂湘粤桂琼渝川贵云藏陕甘青宁新

发证机关代码:ABCDEFGHJKLMNPQRSTUVWXY (无 I, O , Z 三个字母。其中O和Z属于特殊车牌类型)

车牌号码:

数字:0123456789

字母:ABCDEFGHJKLNMxPQRSTUVWXYZ (说明:无 I, O 字母;)

所以1、2、3种车牌匹配的正则表达式如下:

^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[ABCDEFGHJKLMNPQRSTUVWXY]{1}[ABCDEFGHJKLNMxPQRSTUVWXYZ 0-9]{4}[ABCDEFGHJKLNMxPQRSTUVWXYZ 0-9挂学警港澳]{1}$

关于新能源车牌:

车牌匹配正则表达式如下:

^[京津晋冀蒙辽吉黑沪苏浙皖闽赣鲁豫鄂湘粤桂琼渝川贵云藏陕甘青宁新][ABCDEFGHJKLMNPQRSTUVWXY][1-9DF][1-9ABCDEFGHJKLMNPQRSTUVWXYZ]\d{3}[1-9DF]$

二、c++11 regex介绍

C++11 为我们提供了正则表达式库regex,头文件#include <regex>

std::regex类

该类型是有一个代表正则表达式的字符串和一个文法选项作为输入,当文法选项不指定时默认为ECMAScript

std::regex_match匹配函数

std::regex_match是全文匹配,即输入的字符串要和正则表达式全部匹配,才认为匹配成功返回true,否则匹配失败返回false

std::regex_search

std::regex_search是在输入的字符串中不断搜索符合正则表达式描述的子字符串,然后将第一个匹配到的子字符串返回。

std::regex_replace

std::regex_replace是在std::regex_search的基础上将匹配的子字符串替换为提供的字符串。

关于中文

若是正则表达式里有中文字符,就不能使用std::regex类了,要使用std::wregex类,字符串参数也不是string了,要改为wstrig,若提供的参数字符串是string的话,还要把string转换为wstring,不然正则表达式匹配不起作用,不信的人可以自己试一下。

三、示例代码

// CPPstudy.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <regex>
/**
 * @brief string转换为wstring
 * @param strInput 要转换的string字符串 
 * @return 
*/
std::wstring stringToWstring(const std::string& strInput) {
    if (strInput.empty())
    {
        return L"";
    }
    std::string strLocale = setlocale(LC_ALL, "");
    const char* pSrc = strInput.c_str();
    unsigned int iDestSize = mbstowcs(NULL, pSrc, 0) + 1;
    wchar_t* szDest = new wchar_t[iDestSize];
    wmemset(szDest, 0, iDestSize);
    mbstowcs(szDest, pSrc, iDestSize);
    std::wstring wstrResult = szDest;
    delete[]szDest;
    setlocale(LC_ALL, strLocale.c_str());
    return wstrResult;
}


int main()
{
    std::vector<std::string> lps;
    lps.emplace_back("鲁A12345");
    lps.emplace_back("SA12345");
    lps.emplace_back("鲁AD12345");
    lps.emplace_back("鲁AD12");
    lps.emplace_back("鲁AD#1234");
    std::wstring wstr;
    std::wregex reg(L"^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[ABCDEFGHJKLMNPQRSTUVWXY]{1}[ABCDEFGHJKLNMxPQRSTUVWXYZ 0-9]{4}[ABCDEFGHJKLNMxPQRSTUVWXYZ 0-9挂学警港澳]{1}$");
    std::wregex regNew(L"^[京津晋冀蒙辽吉黑沪苏浙皖闽赣鲁豫鄂湘粤桂琼渝川贵云藏陕甘青宁新]{1}[ABCDEFGHJKLMNPQRSTUVWXY]{1}[1-9DF]{1}[1-9ABCDEFGHJKLMNPQRSTUVWXYZ]{4}[1-9DF]$");

    for(std::string str: lps)
    {
        wstr = stringToWstring(str.c_str());
        std::wsmatch match;
        bool ret = std::regex_match(wstr, match, reg);
        if (ret)
        {
            std::cout << str << "匹配成功,是常规车牌、军牌" << std::endl;
        }
        else
        {
            ret = std::regex_match(wstr, match, regNew);
            if (ret)
            {
                std::cout << str << "匹配成功,是新能源车牌" << std::endl;
            }
            else
            {
                std::cout << str << "匹配失败,不是车牌号" << std::endl;
            }
        }
    }
}

运行结果:

java 车牌号正则表达式包含绿牌 车牌号正则表达式匹配_java 车牌号正则表达式包含绿牌_09

  • 注意:程序没有经过严格的测试,正则表达式写的不是很完美,欢迎批评指正。