regexp_ut.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. #include <library/cpp/testing/unittest/registar.h>
  2. #include <util/string/strip.h>
  3. #include <library/cpp/regex/pcre/regexp.h>
  4. #include <util/stream/output.h>
  5. struct TRegTest {
  6. const char* Regexp;
  7. const char* Data;
  8. const char* Result;
  9. int CompileOptions;
  10. int RunOptions;
  11. TRegTest(const char* re, const char* text, const char* res, int copts = REG_EXTENDED, int ropts = 0)
  12. : Regexp(re)
  13. , Data(text)
  14. , Result(res)
  15. , CompileOptions(copts)
  16. , RunOptions(ropts)
  17. {
  18. }
  19. };
  20. struct TSubstTest: public TRegTest {
  21. const char* Replacement;
  22. const char* Replacement2;
  23. TSubstTest(const char* re, const char* text, const char* res, const char* repl, const char* repl2)
  24. : TRegTest(re, text, res, REG_EXTENDED, REGEXP_GLOBAL)
  25. , Replacement(repl)
  26. , Replacement2(repl2)
  27. {
  28. }
  29. };
  30. const TRegTest REGTEST_DATA[] = {
  31. TRegTest("test", "its a test and test string.", "6 10", REG_EXTENDED, 0),
  32. TRegTest("test", "its a test and test string.", "6 10 15 19", REG_EXTENDED, REGEXP_GLOBAL),
  33. TRegTest("test|[an]{0,0}", "test and test an test string tes", "0 4 4 4 5 5 6 6 7 7 8 8 9 13 13 13 14 14 15 15 16 16 17 21 21 21 22 22 23 23 24 24 25 25 26 26 27 27 28 28 29 29 30 30 31 31 32 32", REG_EXTENDED, REGEXP_GLOBAL),
  34. TRegTest("test[an]{1,}", "test and test an test string tes", "NM", REG_EXTENDED, REGEXP_GLOBAL)};
  35. const TSubstTest SUBSTTEST_DATA[] = {
  36. TSubstTest("([a-zA-Z]*[0-9]+) (_[a-z]+)", "Xxx123 534 ___124 bsd _A ZXC _L 141 _sd dsfg QWE123 _bbb", "141 XXX/_sd", "$1 XXX/$2", "$2$2$2 YY$1Y/$2")};
  37. class TRegexpTest: public TTestBase {
  38. private:
  39. regmatch_t Matches[NMATCHES];
  40. private:
  41. UNIT_TEST_SUITE(TRegexpTest);
  42. UNIT_TEST(TestRe)
  43. UNIT_TEST(TestSubst)
  44. UNIT_TEST(TestOffEndOfBuffer);
  45. UNIT_TEST_SUITE_END();
  46. inline void TestRe() {
  47. for (const auto& regTest : REGTEST_DATA) {
  48. memset(Matches, 0, sizeof(Matches));
  49. TString result;
  50. TRegExBase re(regTest.Regexp, regTest.CompileOptions);
  51. if (re.Exec(regTest.Data, Matches, regTest.RunOptions) == 0) {
  52. for (auto& matche : Matches) {
  53. if (matche.rm_so == -1) {
  54. break;
  55. }
  56. result.append(Sprintf("%i %i ", matche.rm_so, matche.rm_eo));
  57. }
  58. } else {
  59. result = "NM";
  60. }
  61. StripInPlace(result);
  62. UNIT_ASSERT_VALUES_EQUAL(result, regTest.Result);
  63. }
  64. }
  65. inline void TestSubst() {
  66. for (const auto& substTest : SUBSTTEST_DATA) {
  67. TRegExSubst subst(substTest.Regexp, substTest.CompileOptions);
  68. subst.ParseReplacement(substTest.Replacement);
  69. TString result = subst.Replace(substTest.Data, substTest.RunOptions);
  70. UNIT_ASSERT_VALUES_EQUAL(result, substTest.Result);
  71. TRegExSubst substCopy = subst;
  72. subst.ParseReplacement(substTest.Replacement2);
  73. TString newResult = subst.Replace(substTest.Data, substTest.RunOptions);
  74. UNIT_ASSERT_VALUES_UNEQUAL(newResult.c_str(), result.c_str());
  75. TString copyResult = substCopy.Replace(substTest.Data, substTest.RunOptions);
  76. UNIT_ASSERT_VALUES_EQUAL(copyResult, result);
  77. substCopy = subst;
  78. copyResult = substCopy.Replace(substTest.Data, substTest.RunOptions);
  79. UNIT_ASSERT_VALUES_EQUAL(copyResult, newResult);
  80. }
  81. }
  82. void TestOffEndOfBuffer() {
  83. const TString needle{".*[^./]gov[.].*"};
  84. TRegExMatch re{needle, REG_UTF8};
  85. const TString haystack{"fakty.ictv.ua"};
  86. UNIT_ASSERT_VALUES_EQUAL(re.Match(haystack.c_str()), false);
  87. }
  88. };
  89. UNIT_TEST_SUITE_REGISTRATION(TRegexpTest);