#include <iostream>
#include <string>
#include <unordered_map>
#include <vector>
#include <algorithm>
#include <optional>
#include <cassert>
#include <future>
bool check(wchar_t* s, wchar_t* p)
{
wchar_t* rs = 0, * rp = 0;
while (1)
if (*p == L'*')
rs = s, rp = ++p;
else if (!*s)
return !*p;
else if (*s == *p || *p == L'?')
++s, ++p;
else if (rs)
s = ++rs, p = rp;
else
return false;
//https://ru.stackoverflow.com/questions/483723/%d0%9a%d0%b0%d0%ba-%d0%bf%d1%80%d0%be%d0%b2%d0%b5%d1%80%d0%b8%d1%82%d1%8c-%d1%81%d0%be%d0%be%d1%82%d0%b2%d0%b5%d1%82%d1%81%d1%82%d0%b2%d0%b8%d0%b5-%d0%b8%d0%bc%d0%b5%d0%bd%d0%b8-%d1%84%d0%b0%d0%b9%d0%bb%d0%b0-%d0%bc%d0%b0%d1%81%d0%ba%d0%b5/483724#483724
}
bool LikeVB(const wchar_t* s, const wchar_t* p)
{
const wchar_t* rs = 0, * rp = 0;
bool res = 0;//result [...]
while (1) {
if (*p == L'[') {
if (*(p + 1) == L']') { p += 2; continue; }// ""=="[]"
bool b = false, match = false;
const wchar_t* pt = p; //p_temp
if (*(++pt) == L'!' && *(pt + 1) != L']') { b = true; ++pt; }//[!...] not [!]
while (*pt != L']') {
if (*pt == L'\0') { throw 93; }//если забыли закрывающую скобку//' Throws Error 93 (invalid pattern string).
if (*(pt + 1) == L'-' && *(pt + 2) != L']')//если есть диапазон ... - ...
{
if (*s >= *pt && *s <= *(pt + 2))
{
if (b) {
res = false; break;
}//если таких символов не должно быть
else {
match = true;
}//если нашли
}
pt += 2; //for [1-4-9]
}
else { //если отдельный символ
if (*s == *pt) {
if (b) {
res = false; break;
}//если таких символов не должно быть
else {
match = true;
}//если нашли
}
++pt;
}
}
if (b == match) {
res = false;
}
else {
res = true;
++s; p = ++pt;//закрывающая скобка
}
}
if (res) {
res = false;
}
else if (*p == L'#' && *s <= L'9' && *s >= L'0') {
++s, ++p;
}
else if (*p == L'*') {
rs = s, rp = ++p;
}
else if (!*s) {
return !*p;
}
else if (*p == L'?' || *s == *p && *p != L'[' && *p != L'#') {
++s, ++p;
}
else if (rs) {
s = ++rs, p = rp;
}
else {
return false;
}
}
}
int main()
{
try {
int iMax = 16000000;// 16000000;
std::chrono::steady_clock::time_point timeStart;
std::chrono::steady_clock::time_point timeStop;
std::vector < std::vector<const wchar_t* >> testArr =
{
{L"XYXZZXYXYXZZXY", L"*X*X?*X*X?",L"True"}, //' Speed test
{L"aBBBa", L"a*a",L"True"},
{L"F" , L"[A-Z]" ,L"True"},
{L"F" , L"[!A-Z]",NULL},
{L"a2a" , L"a#a", L"True"},
{L"aM5b" , L"a[L-P]#[!c-e]", L"True"},
{L"BAT123khg" , L"B?T*", L"True"},
{L"CAT123khg" , L"B?T*",NULL},
{L"ab" , L"a*b",L"True"},
{L"a*b" , L"a [*]b", NULL},
{L"axxxxxb" , L"a [*]b",NULL},
{L"a [xyz" , L"a [[]*", L"True"},
{L"aM5b" , L"a*?b", L"True"},
{L"aM5b" , L"a*[1-4-9][!c-e]", L"True"},
{L"aM55b" , L"a*[1-4-9][!c-e]", L"True"},
{L"aM55b" , L"a*[1-45-9][!c-e]", L"True"},
{L"aM5b" , L"*#[!c-e]", L"True"},
{L"5*", L"5[*]", L"True"},
{L"?n", L"[?]n", L"True"},
{L"a", L"[a-cdf]", L"True"},
{L"b", L"[a-cdf]", L"True"},
{L"c", L"[a-cdf]", L"True"},
{L"d", L"[a-cdf]", L"True"},
{L"f", L"[a-cdf]", L"True"},
{L"-", L"[-acdf]", L"True"},
{L"a", L"[-acdf]", L"True"},
{L"c", L"[-acdf]", L"True"},
{L"d", L"[-acdf]", L"True"},
{L"f", L"[-acdf]", L"True"},
{L"[", L"[ [ ]", L"True"},
{L"]", L"]", L"True"},
{L"abc_d", L"abc[_]d*", L"True"},
{L"abc_de", L"abc[_]d*", L"True"},
{L"abcd", L"abc[def]", L"True"},
{L"abce", L"abc[def]", L"True"},
{L"abcf", L"abc[def]", L"True"},
{L"abcdef", L"abc*[de]ef", L"True"},
{L"abcyef", L"abc[xz]ef", NULL},
{L"abcxef", L"abc[xz]ef", L"True"},
{L"abcyef", L"abc[!xz]ef", L"True"},
{L"abcxef", L"abc[!xz]ef", NULL},
{L"ac5c5b", L"a*[1-56-9][!c-e]", L"True"},
{L"", L"", L"True"},
{L"", L"*", L"True"},
{L"", L"[]", L"True"},
{L"", L"[!]", NULL},
{L"", L"[]*", L"True"},
{L"", L"[!]*", NULL},
{L"1", L"[!]*", NULL},
{L"1", L"[]*", L"True"},
{L"1", L"[!]*", NULL},
{L"1", L"[!]", NULL},
{L"1", L"*[!]", NULL},
{L"1", L"*[]", L"True"},
{L"1", L"#[]", L"True"},
{L"1", L"#[!]", NULL},
{L"12", L"#[!]", NULL},
{L"12", L"#[!]*", NULL},
{L"123", L"*[!]*", NULL},
{L"1!3", L"*[!]*", L"True"},
{L"!", L"*[!]*", L"True"},
{L"!", L"[!]", L"True"},
{L"!a", L"*[!a]*", L"True"},
{L"!a", L"[!a]*", L"True"},
{L"!a", L"*[!a]", NULL},
{L"!a", L"[!a]", NULL},
{L"a", L"[!a]", NULL},
{L"b", L"[!a]", L"True"},
{L"2", L"#[]", L"True"},
{L"*", L"[*]", L"True"},
{L"1", L"[*]", NULL},
{L"!", L"[!-!]", NULL},
{L"1", L"[!-!]", L"True"},
{L"!", L"[-!]", L"True"},
{L"!", L"[!-]", L"True"},
{L"-", L"[!-]", NULL},
{L"-", L"[-]", L"True"},
{L"***", L"*[*]*", L"True"},
{L"???", L"?[?]?", L"True"},
{L"###", L"#[#]#", NULL},
{L"[[[[[", L"[[]?*[[]", L"True"},
//{L"a [xyz" , L"a [*", NULL} //' Throws Error 93 (invalid pattern string).
};
std::wcout << L"Test pattern...";
std::wcout << L"\n\nLikeVB...";
for (int i = 0; i < testArr.size(); i++) {
if (LikeVB(testArr[i][0], testArr[i][1]) != (bool)testArr[i][2]) {
std::wcout << std::wstring(L"\nERR: string, pattern-> '") + testArr[i][0] + L"', '" + testArr[i][1] + L"'" + L"', ";
std::wcout << (bool)testArr[i][2];
}
}
bool result = 0;
std::wcout << L"\n\nSpeed test...";
for(int try_=0; try_<10; try_++)
{
timeStart = std::chrono::steady_clock::now();
for (int i = 0; i < iMax; i++) {
result = check((wchar_t*)testArr[0][0], (wchar_t*)testArr[0][1]);
}
timeStop = std::chrono::steady_clock::now();
std::wcout << L"\ncheck, ms: " + std::to_wstring(std::chrono::duration_cast<std::chrono::milliseconds> (timeStop - timeStart).count());
std::wcout << L"\t" << result;
}
std::wcout << L"\n";
for(int try_=0; try_<10; try_++)
{
timeStart = std::chrono::steady_clock::now();
for (int i = 0; i < iMax; i++) {
result = LikeVB(testArr[0][0], testArr[0][1]);
}
timeStop = std::chrono::steady_clock::now();
std::wcout << L"\nLikeVB, ms: " + std::to_wstring(std::chrono::duration_cast<std::chrono::milliseconds> (timeStop - timeStart).count());
std::wcout << L"\t" << result;
}
std::wcout << L"\n";
std::ignore=system("pause");
return 0;
}
catch (int& e) { std::ignore=system("pause"); return e; }
catch (...) { std::ignore=system("pause"); return -1; }
}