c++11 regex 正則表示式驗證車牌號
在使用c++11 regex驗證車牌號前,要首先明白有幾個坑要踩:
1.車牌號校驗規則,只有弄清楚了校驗車牌號的規則才能寫出正確的正則表示式,所以首先要弄清楚車牌號的校驗規則。
2.c++11 中regex的用法,其中用到了regex、 regex_match,其中有個坑就是中文的匹配。
一、車牌號校驗規則
1.普通常見車牌(藍牌、黃牌)
車牌號碼的長度:7位 , 第一位是省份簡稱, 第二位是發證機關程式碼,第二位到第七位是大寫英文字元和阿拉伯數字組成。例如:京A88888
2.最後一位為漢字的車牌。
車牌號碼的長度:7位 , 第一位是省份簡稱, 第二位是發證機關程式碼,第二位到第六位是大寫英文字元和阿拉伯數字組成。最後一個字元為漢字,漢字包括“掛”、“學”、“警”、“港”、“澳”。比如:魯A8888學
3.新軍車牌
以兩位為大寫英文字母開頭,後面以5位阿拉伯數字組成。如:KA12345。
4.新能源車牌
車牌號碼的長度:8位 , 第一位是省份簡稱, 第二位是發證機關程式碼,按照現行新能源車牌號碼規則:
第三位:1-9DF;
第四位:1-9A-Z,無I、O字母;
第五-七位:0-9;
第八位:1-9DF;
關於第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_match是全文匹配,即輸入的字串要和正則表示式全部匹配,才認為匹配成功返回true,否則匹配失敗返回false
std::regex_search是在輸入的字串中不斷搜尋符合正則表示式描述的子字串,然後將第一個匹配到的子字串返回。
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;
}
}
}
}
執行結果:
- 注意:程式沒有經過嚴格的測試,正則表示式寫的不是很完美,歡迎批評指正。