diff --git a/Readme.md b/Readme.md index 72738d0..62bbc59 100644 --- a/Readme.md +++ b/Readme.md @@ -13,22 +13,27 @@ Unique algorithms that was implemented on native unmanaged C++ but easily access [![Build history](https://buildstats.info/appveyor/chart/3Fs/regxwild-github?buildCount=20&includeBuildsFromPullRequest=true&showStats=true)](https://ci.appveyor.com/project/3Fs/regxwild-github/history) +Samples [⏯](regXwildTest/EssSamplesTest.cpp) | regXwild filter | n +----------------------|----------------------|--------- +number = '1271'; | number = '????'; | 0 - 4 +year = '2020'; | '##'\|'####' | 2; 4 +year = '20'; | = '##??' | 2; 4 +number = 888; | number = +??; | 1 - 3 + + +Samples [⏯](regXwildTest/EssSamplesTest.cpp) | regXwild filter +----------------------|---------------------- +everything is ok | ^everything\*ok$ +systems | system? +systems | sys###s +A new 'X1' project | ^A\*'+' pro?ect +professional system | pro\*system +regXwild in action | pro?ect$\|open\*source+act\|^regXwild -```cpp -= searchEssC(L"number = '1271';", L"number = '????';", true); -``` -```cpp -= searchEss(data, _T("^main*is ok$")); -= searchEss(data, _T("^new*pro?ection")); -= searchEss(data, _T("pro*system")); -= searchEss(data, _T("sys###s")); -= searchEss(data, _T("new+7+system")); -= searchEss(data, _T("some project$|open*and*star|^system")); -``` ## Why regXwild ? -It was designed to be faster than just fast, when using more features that usually go beyond the typical wildcards. +It was designed to be faster than just fast for features that usually go beyond the typical wildcards. Seriously, We love regex, I love, You love; 2013 far behind but regXwild still relevant for speed and powerful wildcards-like features, such as `##??` (which means 2 or 4) ... ### 🔍 Easy to start @@ -58,43 +63,42 @@ using(var l = new ConariL("regXwild.dll")) ESS version (advanced EXT version) -```cpp -enum MetaSymbols -{ - MS_ANY = _T('*'), // {0, ~} - MS_SPLIT = _T('|'), // str1 or str2 or ... - MS_ONE = _T('?'), // {0, 1}, ??? {0, 3}, ... - MS_BEGIN = _T('^'), // [str... or [str1... |[str2... - MS_END = _T('$'), // ...str] or ...str1]| ...str2] - MS_MORE = _T('+'), // {1, ~}, +++ {3, ~}, ... - MS_SINGLE = _T('#'), // {1}, ## {2}, ### {3}, ... - MS_ANYSP = _T('>'), // as [^/]* -}; -``` +metasymbol | meaning +-----------|---------------- +\* | {0, ~} +\| | str1 or str2 or ... +? | {0, 1}, ??? {0, 3}, ... +^ | [str... or [str1... |[str2... +$ | ...str] or ...str1]| ...str2] +\+ | {1, ~}, +++ {3, ~}, ... +\# | {1}, ## {2}, ### {3}, ... +\> | as [^/]* EXT version (more simplified than ESS) -```cpp -enum MetaSymbols -{ - MS_ANY = _T('*'), - MS_ANYSP = _T('>'), //as [^/\\]+ - MS_SPLIT = _T('|'), - MS_ONE = _T('?'), -}; -``` - -🧮 Quantifiers - -regex | regXwild ----------|---------- -.* | * -.+ | + -.? | ? -.{1} | # -.{2} | ## -.{2, } | ++ -.{0, 2} | ?? +metasymbol | meaning +-----------|---------------- +\* | {0, ~} +\> | as [^/\\]+ +\| | str1 or str2 or ... +? | {0, 1}, ??? {0, 3}, ... + + +### 🧮 Quantifiers + +regex | regXwild | n +----------------|------------|--------- +.\* | \* | 0+ +.+ | + | 1+ +.? | ? | 0; 1 +.{1} | # | 1 +.{2} | ## | 2 +.{2, } | ++ | 2+ +.{0, 2} | ?? | 0 - 2 +.{2, 4} | ++?? | 2 - 4 +(?:.{2}\|.{4}) | ##?? | 2; 4 +.{3, 4} | +++? | 3 - 4 +(?:.{1}\|.{3}) | #?? | 1; 3 and similar ... diff --git a/regXwild.nuspec b/regXwild.nuspec index 0f21534..b30c2bf 100644 --- a/regXwild.nuspec +++ b/regXwild.nuspec @@ -3,7 +3,7 @@ regXwild 1.2.0 - [ regXwild ] Fast advanced wildcards + [ regXwild ] Fast Advanced wildcards github.com/3F/regXwild LICENSE reg @@ -11,27 +11,40 @@ https://github.com/3F/regXwild false - - Small and super Fast advanced wildcards! `*,|,?,^,$,+,#,>` in addition to slow regex engine and more. + Small and super Fast Advanced wildcards! `*,|,?,^,$,+,#,>` in addition to slow regex engines and more. Unique algorithms that was implemented on native unmanaged C++ but easily accessible also in .NET through Conari (recommended due to caching of 0x29 opcodes and other related optimization). + Samples [⏯](run) | regXwild filter | n + ----------------------|----------------------|--------- + number = '1271'; | number = '????'; | 0 - 4 + year = '2020'; | '##'|'####' | 2; 4 + year = '20'; | = '##??' | 2; 4 + number = 888; | number = +??; | 1 - 3 + ... + ----------------------|---------------------- + everything is ok | ^everything*ok$ + systems | system? + systems | sys###s + A new 'X1' project | ^A*'+' pro?ect + professional system | pro*system + regXwild in action | pro?ect$|open*source+act|^regXwild + + This package contains x64 + x32 Unicode + MultiByte modules and provides both support of the unmanaged and managed projects: * For native: .\lib\native\{Platform}-(Unicode or MultiByte)\ ~ regXwild.dll, regXwild.lib, regXwild.exp, include\*.h * For .NET it will put x32 & x64 regXwild into (TargetDir). Use it with your .net modules through Conari ( https://github.com/3F/Conari ) and so on. - ``` - = searchEssC(L"number = '1271';", L"number = '????';", true); - ``` - ## Why regXwild ? - It was designed to be faster than just fast, when using more features that usually go beyond the typical wildcards. + It was designed to be faster than just fast for features that usually go beyond the typical wildcards. + Seriously, We love regex, I love, You love; 2013 far behind but regXwild still relevant for speed and powerful wildcards-like features, + such as `##??` (which means 2 or 4) ... - 🔍 Easy to start: + 🔍 Easy to start Unmanaged native C++ or managed .NET project. It doesn't matter, just use it: @@ -55,44 +68,47 @@ } ``` - 🏄 Amazing meta symbols: + 🏄 Amazing meta symbols ESS version (advanced EXT version) - ```cpp - enum MetaSymbols - { - MS_ANY = _T('*'), // {0, ~} - MS_SPLIT = _T('|'), // str1 or str2 or ... - MS_ONE = _T('?'), // {0, 1}, ??? - {0, 3}, ... - MS_BEGIN = _T('^'), // [str... or [str1... |[str2... - MS_END = _T('$'), // ...str] or ...str1]| ...str2] - MS_MORE = _T('+'), // {1, ~} - MS_SINGLE = _T('#'), // {1} - MS_ANYSP = _T('>'), // as [^/]* - }; - ``` - - EXT version (more simplified than ESS) - - ```cpp - enum MetaSymbols - { - MS_ANY = _T('*'), - MS_ANYSP = _T('>'), //as [^/\\]+ - MS_SPLIT = _T('|'), - MS_ONE = _T('?'), - }; - ``` - - Check it with our actual **Unit-Tests**. - - 🚀 Awesome speed: + metasymbol | meaning + -----------|---------------- + * | {0, ~} + | | str1 or str2 or ... + ? | {0, 1}, ??? {0, 3}, ... + ^ | [str... or [str1... |[str2... + $ | ...str] or ...str1]| ...str2] + + | {1, ~}, +++ {3, ~}, ... + # | {1}, ## {2}, ### {3}, ... + > | as [^/]* + + 🧮 Quantifiers + + regex | regXwild | n + ----------------|------------|--------- + .* | * | 0+ + .+ | + | 1+ + .? | ? | 0; 1 + .{1} | # | 1 + .{2} | ## | 2 + .{2, } | ++ | 2+ + .{0, 2} | ?? | 0 - 2 + .{2, 4} | ++?? | 2 - 4 + (?:.{2}|.{4}) | ##?? | 2; 4 + .{3, 4} | +++? | 3 - 4 + (?:.{1}|.{3}) | #??? | 1; 3 + + and similar ... + + Play with our actual **Unit-Tests**. + + 🚀 Awesome speed * [~2000 times faster when C++](https://github.com/3F/regXwild#speed). * For .NET (including modern .NET Core), [Conari](https://github.com/3F/Conari) provides optional caching of 0x29 opcodes (Calli) and more to get a similar result as possible. - 🍰 Open and Free: + 🍰 Open and Free Open Source project; MIT License, Enjoy 🎉 @@ -100,16 +116,13 @@ https://github.com/3F/regXwild - - - - - - - - - - - - - - - - - ~~~~~~~~ - Get it via GetNuTool: - =================================== + ======================================= gnt /p:ngpackages="regXwild/1.2.0" - =================================== - * https://github.com/3F/GetNuTool - + ================== https://github.com/3F/GetNuTool + - Small and super Fast advanced wildcards! `*,|,?,^,$,+,#,>` in addition to slow regex engine and more. https://github.com/3F/regXwild - wildcards advanced-wildcards fast-wildcards fast-regex extended-wildcards strings text filter search matching search-in-text regex filters powerful-wildcards regexp cpp c dotnet dotnetcore csharp Conari regXwild native + Small and super Fast advanced wildcards! `*,|,?,^,$,+,#,>` in addition to slow regex engines and more. https://github.com/3F/regXwild + wildcards advanced-wildcards fast-wildcards fast-regex extended-wildcards strings text filter search matching search-in-text regex glob filters powerful-wildcards regexp cpp c dotnet dotnetcore csharp Conari regXwild native changelog: https://github.com/3F/regXwild/blob/master/changelog.txt Copyright (c) 2013-2014, 2016-2017, 2020 Denis Kuzmin < x-3F@outlook.com > GitHub/3F diff --git a/regXwild/core/ESS/AlgorithmEss.cpp b/regXwild/core/ESS/AlgorithmEss.cpp index 4eab29c..dbfdf85 100644 --- a/regXwild/core/ESS/AlgorithmEss.cpp +++ b/regXwild/core/ESS/AlgorithmEss.cpp @@ -117,24 +117,22 @@ bool AlgorithmEss::search(const tstring& text, const tstring& filter, bool ignor if(rewindToNextBlock(it)){ continue; } return false; } + // ++?? and ##?? + if(item.mask.prev & (MORE | SINGLE) && item.mask.curr & ONE) + { + item.mixpos = item.overlay + 1; + item.mixms = item.mask.prev; + } + // Sequential combinations of #, ?, + if((item.mask.curr & SINGLE && item.mask.prev & SINGLE) || (item.mask.curr & ONE && item.mask.prev & ONE) || (item.mask.curr & MORE && item.mask.prev & MORE)) { - ++item.overlay; + ++item.overlay; } else{ item.overlay = 0; } - // disable all combinations for SINGLE. TODO: stub - _stubSINGLECombination() - if( (item.mask.prev & (BOL | EOL)) == 0 && - ( - (item.mask.curr & SINGLE && (item.mask.prev & SINGLE) == 0) || - (item.mask.prev & SINGLE && (item.mask.curr & SINGLE) == 0) )) - { - if(rewindToNextBlock(it)){ continue; } return false; - } - ++item.pos; // TODO: implement non-sequential MS combinations ~ unsigned short int .. @@ -211,8 +209,10 @@ bool AlgorithmEss::search(const tstring& text, const tstring& filter, bool ignor } item.pos = item.left; - if(item.mask.curr & SPLIT) { + if(item.mask.curr & SPLIT) + { words.left = 0; + item.mixpos = 0; item.mask.prev = BOL; continue; //to next block } @@ -253,6 +253,31 @@ bool AlgorithmEss::search(const tstring& text, const tstring& filter, bool ignor udiff_t AlgorithmEss::interval() { + // ++?? or ##?? + if(item.mask.prev & ONE && item.mixpos > 0) + { + size_t len = item.prev.length(); + diff_t delta = words.found - words.left; + + diff_t min = item.mixpos; + diff_t max = min + item.overlay + 1; + + if(item.mixms & SINGLE && delta != min && delta != max) { + return tstring::npos; + } + + if(delta < min || delta > max) { + return tstring::npos; + } + + if(_text.substr(words.found - len - delta, len).compare(item.prev) == 0) { + return words.found; + } + + return tstring::npos; + + } + // "#" if(item.mask.prev & SINGLE) { diff --git a/regXwild/core/ESS/AlgorithmEss.h b/regXwild/core/ESS/AlgorithmEss.h index cf1d34a..d15a511 100644 --- a/regXwild/core/ESS/AlgorithmEss.h +++ b/regXwild/core/ESS/AlgorithmEss.h @@ -91,17 +91,20 @@ namespace net { namespace r_eg { namespace regXwild { namespace core { namespace Mask mask; unsigned short int overlay; + unsigned short int mixpos; // ++?? + MetaOperation mixms; + /** enough of this.. */ tstring prev; void reset() { - pos = left = delta = overlay = 0; + pos = left = delta = overlay = mixpos = 0; mask.curr = mask.prev = BOL; curr.clear(); prev.clear(); }; - Item(): pos(0), left(0), delta(0), overlay(0) { }; + Item(): pos(0), left(0), delta(0), overlay(0), mixpos(0) { }; } item; /** diff --git a/regXwildTest/AlgorithmEssTest.cpp b/regXwildTest/AlgorithmEssTest.cpp index 01bca25..b02853b 100644 --- a/regXwildTest/AlgorithmEssTest.cpp +++ b/regXwildTest/AlgorithmEssTest.cpp @@ -882,44 +882,6 @@ namespace regXwildTest } } - /* behaviour by default for non implemented combinations - SINGLE */ - TEST_METHOD(stubSINGLECombinationTest1) - { - tstring data = _T("new tes;ted project-12, and 75_protection of various systems"); - - // MS combination - { - //TODO: implement *,>,?,+,# and combination - { - /* true: */ - - // * - { - Assert::AreEqual(false, searchEss(data, _T("*#"))); - Assert::AreEqual(false, searchEss(data, _T("*#*"))); - Assert::AreEqual(false, searchEss(data, _T("#*"))); - Assert::AreEqual(false, searchEss(data, _T("*#systems"))); - Assert::AreEqual(false, searchEss(data, _T("new*#*systems"))); - Assert::AreEqual(false, searchEss(data, _T("*new#*systems*"))); - Assert::AreEqual(false, searchEss(data, _T("new#*systems"))); - Assert::AreEqual(false, searchEss(data, _T("75*#protection"))); - Assert::AreEqual(false, searchEss(data, _T("75*#*protection"))); - Assert::AreEqual(false, searchEss(data, _T("new*#systems"))); - Assert::AreEqual(false, searchEss(data, _T("*new#*#systems*"))); - } - - /* false */ - { - Assert::AreEqual(false, searchEss(data, _T("*new#systems*"))); - Assert::AreEqual(false, searchEss(data, _T("*new##systems*"))); - Assert::AreEqual(false, searchEss(data, _T("systems*#"))); - Assert::AreEqual(false, searchEss(data, _T("pro#*ject"))); - Assert::AreEqual(false, searchEss(data, _T("systems#*"))); - } - } - } - } - /* behaviour by default for non implemented combinations - END */ TEST_METHOD(stubENDCombinationTest1) { diff --git a/regXwildTest/AlgorithmExtTest.cpp b/regXwildTest/AlgorithmExtTest.cpp index dd30305..8a251b9 100644 --- a/regXwildTest/AlgorithmExtTest.cpp +++ b/regXwildTest/AlgorithmExtTest.cpp @@ -105,6 +105,19 @@ namespace regXwildTest Assert::AreEqual(false, searchExt(_T("system_-17 fee also"), _T("system?17"))); } + TEST_METHOD(filterOneTest3) + { + tstring data = _T("number = '1234';"); + + Assert::IsTrue, searchExt(data, _T("'????'")); + Assert::IsTrue, searchExt(data, _T("'?????'")); + Assert::IsTrue, searchExt(data, _T("'??????'")); + Assert::IsFalse, searchExt(data, _T("'???'")); + Assert::IsFalse, searchExt(data, _T("'??'")); + Assert::IsFalse, searchExt(data, _T("'?'")); + Assert::IsFalse, searchExt(data, _T("''")); + } + TEST_METHOD(filterAnySPTest1) { Assert::AreEqual(true, searchExt(_T("/new/user_myhid_test.bzip2"), _T("myhid>bzip"))); // __...___ diff --git a/regXwildTest/EssRangesTest.cpp b/regXwildTest/EssRangesTest.cpp index 53237aa..9e9e083 100644 --- a/regXwildTest/EssRangesTest.cpp +++ b/regXwildTest/EssRangesTest.cpp @@ -15,16 +15,124 @@ namespace regXwildTest { public: + TEST_METHOD(minmaxRangeTest1) + { + tstring filter = _T("'++??'"); // 2-4 + + Assert::IsFalse(searchEss(_T("number = '';"), filter)); + Assert::IsFalse(searchEss(_T("number = '1';"), filter)); + Assert::IsTrue(searchEss(_T("number = '12';"), filter)); + Assert::IsTrue(searchEss(_T("number = '123';"), filter)); + Assert::IsTrue(searchEss(_T("number = '1234';"), filter)); + Assert::IsFalse(searchEss(_T("number = '12345';"), filter)); + } + + TEST_METHOD(minmaxRangeTest2) + { + tstring filter = _T("= '+++??'"); // 3-5 + + Assert::IsFalse(searchEss(_T("number = '';"), filter)); + Assert::IsFalse(searchEss(_T("number = '1';"), filter)); + Assert::IsFalse(searchEss(_T("number = '12';"), filter)); + Assert::IsTrue(searchEss(_T("number = '123';"), filter)); + Assert::IsTrue(searchEss(_T("number = '1234';"), filter)); + Assert::IsTrue(searchEss(_T("number = '12345';"), filter)); + Assert::IsFalse(searchEss(_T("number = '123456';"), filter)); + Assert::IsFalse(searchEss(_T("number = '1234567';"), filter)); + } + + TEST_METHOD(minmaxRangeTest3) + { + tstring filter = _T("= '+?'"); // 1-2 + + Assert::IsFalse(searchEss(_T("number = '';"), filter)); + Assert::IsTrue(searchEss(_T("number = '1';"), filter)); + Assert::IsTrue(searchEss(_T("number = '12';"), filter)); + Assert::IsFalse(searchEss(_T("number = '123';"), filter)); + } + + TEST_METHOD(minmaxRangeTest4) + { + tstring filter = _T("number = '+??';"); // 1-3 + + Assert::IsFalse(searchEss(_T("number = '';"), filter)); + Assert::IsTrue(searchEss(_T("number = '1';"), filter)); + Assert::IsTrue(searchEss(_T("number = '12';"), filter)); + Assert::IsTrue(searchEss(_T("number = '123';"), filter)); + Assert::IsFalse(searchEss(_T("number = '1234';"), filter)); + } + TEST_METHOD(minmaxRangeTest5) { - tstring filter = _T("year = '##'|year = '####'"); // 2 or 4 + tstring filter = _T("year = '++??';"); // 2-4 + + Assert::IsTrue(searchEss(_T("year = '2020';"), filter)); + Assert::IsTrue(searchEss(_T("year = '20';"), filter)); + Assert::IsTrue(searchEss(_T("year = '20y';"), filter)); + Assert::IsFalse(searchEss(_T("year = '2';"), filter)); + Assert::IsFalse(searchEss(_T("year = '2020y';"), filter)); + Assert::IsFalse(searchEss(_T("year = 2020;"), filter)); + } + + TEST_METHOD(minOrMaxTest1) + { + tstring filter = _T("year = '##??';"); // 2 or 4 only Assert::IsTrue(searchEss(_T("year = '2020';"), filter)); Assert::IsTrue(searchEss(_T("year = '20';"), filter)); + Assert::IsFalse(searchEss(_T("year = '20y';"), filter)); + Assert::IsFalse(searchEss(_T("year = '2';"), filter)); Assert::IsFalse(searchEss(_T("year = '2020y';"), filter)); Assert::IsFalse(searchEss(_T("year = 2020;"), filter)); } + TEST_METHOD(minOrMaxTest2) + { + tstring filter = _T("'##??'"); // 2 or 4 + + Assert::IsFalse(searchEss(_T("number = '';"), filter)); + Assert::IsFalse(searchEss(_T("number = '1';"), filter)); + Assert::IsTrue(searchEss(_T("number = '12';"), filter)); + Assert::IsFalse(searchEss(_T("number = '123';"), filter)); + Assert::IsTrue(searchEss(_T("number = '1234';"), filter)); + Assert::IsFalse(searchEss(_T("number = '12345';"), filter)); + } + + TEST_METHOD(minOrMaxTest3) + { + tstring filter = _T("= '###??'"); // 3 or 5 + + Assert::IsFalse(searchEss(_T("number = '';"), filter)); + Assert::IsFalse(searchEss(_T("number = '1';"), filter)); + Assert::IsFalse(searchEss(_T("number = '12';"), filter)); + Assert::IsTrue(searchEss(_T("number = '123';"), filter)); + Assert::IsFalse(searchEss(_T("number = '1234';"), filter)); + Assert::IsTrue(searchEss(_T("number = '12345';"), filter)); + Assert::IsFalse(searchEss(_T("number = '123456';"), filter)); + Assert::IsFalse(searchEss(_T("number = '1234567';"), filter)); + } + + TEST_METHOD(minOrMaxTest4) + { + tstring filter = _T("= '#?'"); // 1 or 2 + + Assert::IsFalse(searchEss(_T("number = '';"), filter)); + Assert::IsTrue(searchEss(_T("number = '1';"), filter)); + Assert::IsTrue(searchEss(_T("number = '12';"), filter)); + Assert::IsFalse(searchEss(_T("number = '123';"), filter)); + } + + TEST_METHOD(minOrMaxTest5) + { + tstring filter = _T("number = '#??';"); // 1 or 3 + + Assert::IsFalse(searchEss(_T("number = '';"), filter)); + Assert::IsTrue(searchEss(_T("number = '1';"), filter)); + Assert::IsFalse(searchEss(_T("number = '12';"), filter)); + Assert::IsTrue(searchEss(_T("number = '123';"), filter)); + Assert::IsFalse(searchEss(_T("number = '1234';"), filter)); + } + TEST_METHOD(rangeAtOneTest1) { tstring data = _T("number = '123';"); diff --git a/regXwildTest/EssSamplesTest.cpp b/regXwildTest/EssSamplesTest.cpp new file mode 100644 index 0000000..66e50c9 --- /dev/null +++ b/regXwildTest/EssSamplesTest.cpp @@ -0,0 +1,61 @@ +#include "stdafx.h" +#include "CppUnitTest.h" + +#include "..\regXwild\regXwildAPI.h" + +using namespace Microsoft::VisualStudio::CppUnitTestFramework; +using namespace net::r_eg::regXwild; + + +namespace regXwildTest +{ + namespace regXwild = net::r_eg::regXwild; + + TEST_CLASS(EssSamplesTest) + { + public: + + TEST_METHOD(sReadmeTest1) + { + Assert::IsTrue(searchEss(_T("number = '1271';"), _T("number = '????';"))); + Assert::IsTrue(searchEss(_T("year = '2020';"), _T("'##'|'####'"))); + Assert::IsTrue(searchEss(_T("year = '20';"), _T("= '##??'"))); + Assert::IsTrue(searchEss(_T("number = 888;"), _T("number = +??;"))); + + // opposite data + + Assert::IsFalse(searchEss(_T("number = '12710';"), _T("number = '????';"))); + Assert::IsFalse(searchEss(_T("year = '2020y';"), _T("'##'|'####'"))); + Assert::IsFalse(searchEss(_T("year = '20y';"), _T("= '##??'"))); + Assert::IsFalse(searchEss(_T("number = 8888;"), _T("number = +??;"))); + } + + TEST_METHOD(sReadmeTest2) + { + Assert::IsTrue(searchEss(_T("everything is ok"), _T("^everything*ok$"))); + Assert::IsTrue(searchEss(_T("systems"), _T("system?"))); + Assert::IsTrue(searchEss(_T("systems"), _T("sys###s"))); + Assert::IsTrue(searchEss(_T("A new 'X1' project"), _T("^A*'+' pro?ect"))); + Assert::IsTrue(searchEss(_T("professional system"), _T("pro*system"))); + Assert::IsTrue(searchEss(_T("regXwild in action"), _T("pro?ect$|open*source+act|^regXwild"))); + + // opposite data + + Assert::IsFalse(searchEss(_T("everything is okay"), _T("^everything*ok$"))); + Assert::IsTrue(searchEss(_T("system"), _T("system?"))); + Assert::IsFalse(searchEss(_T("sys-tems"), _T("sys###s"))); + Assert::IsTrue(searchEss(_T("An amazing 'Y2' protect"), _T("^A*'+' pro?ect"))); + Assert::IsTrue(searchEss(_T("protecting system"), _T("pro*system"))); + Assert::IsTrue(searchEss(_T("opensource project regXwild in action"), _T("pro?ect$|open*source+act|^regXwild"))); + } + + + private: + + bool searchEss(const tstring& data, const tstring& filter) + { + return regXwild::searchEss(data, filter, false); + } + + }; +} \ No newline at end of file diff --git a/regXwildTest/EssSplitTest.cpp b/regXwildTest/EssSplitTest.cpp new file mode 100644 index 0000000..00374c2 --- /dev/null +++ b/regXwildTest/EssSplitTest.cpp @@ -0,0 +1,60 @@ +#include "stdafx.h" +#include "CppUnitTest.h" + +#include "..\regXwild\regXwildAPI.h" + +using namespace Microsoft::VisualStudio::CppUnitTestFramework; +using namespace net::r_eg::regXwild; + + +namespace regXwildTest +{ + namespace regXwild = net::r_eg::regXwild; + + TEST_CLASS(EssSplitTest) + { + public: + + TEST_METHOD(splitTest1) + { + tstring filter = _T("'##'|'####'"); + + Assert::IsTrue(searchEss(_T("year = '2020';"), filter)); + Assert::IsTrue(searchEss(_T("year = '20';"), filter)); + Assert::IsFalse(searchEss(_T("year = '20y';"), filter)); + Assert::IsFalse(searchEss(_T("year = '2020y';"), filter)); + Assert::IsFalse(searchEss(_T("year = 2020;"), filter)); + } + + TEST_METHOD(splitTest2) + { + tstring filter = _T("year = '####'|year = '##'"); + + Assert::IsTrue(searchEss(_T("year = '2020';"), filter)); + Assert::IsTrue(searchEss(_T("year = '20';"), filter)); + Assert::IsFalse(searchEss(_T("year = '2020y';"), filter)); + Assert::IsFalse(searchEss(_T("year = 2020;"), filter)); + } + + TEST_METHOD(splitTest3) + { + tstring filter = _T("str = '+++?'|str = '????'"); + + Assert::IsFalse(searchEss(_T("str = '12345'"), filter)); + Assert::IsTrue(searchEss(_T("str = '1234'"), filter)); + Assert::IsTrue(searchEss(_T("str = '123'"), filter)); + Assert::IsTrue(searchEss(_T("str = '12'"), filter)); + Assert::IsTrue(searchEss(_T("str = '1'"), filter)); + Assert::IsTrue(searchEss(_T("str = ''"), filter)); + } + + + private: + + bool searchEss(const tstring& data, const tstring& filter) + { + return regXwild::searchEss(data, filter, true); + } + + }; +} \ No newline at end of file diff --git a/regXwildTest/regXwildTest.vcxproj b/regXwildTest/regXwildTest.vcxproj index 96c66db..d95439e 100644 --- a/regXwildTest/regXwildTest.vcxproj +++ b/regXwildTest/regXwildTest.vcxproj @@ -165,6 +165,8 @@ + + Create Create diff --git a/regXwildTest/regXwildTest.vcxproj.filters b/regXwildTest/regXwildTest.vcxproj.filters index 06ac63e..e295482 100644 --- a/regXwildTest/regXwildTest.vcxproj.filters +++ b/regXwildTest/regXwildTest.vcxproj.filters @@ -35,5 +35,11 @@ Source Files + + Source Files + + + Source Files + \ No newline at end of file