try-re.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. #include <regex.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. regex_t regex;
  5. #define MAX_MATCH 5
  6. // This is the number of capture groups + 1
  7. #define RESET "\x1b[0m"
  8. int regmatch(regex_t *preg, const char *string, size_t nmatch,
  9. regmatch_t pmatch[], int eflags) {
  10. // returns number of matches found. (Max nmatch)
  11. int matches = 0;
  12. int offset = 0;
  13. int ret;
  14. while (matches < nmatch) {
  15. ret = regexec(preg, string + offset, nmatch - matches, pmatch + matches,
  16. eflags);
  17. if (!ret) {
  18. int current = offset;
  19. offset += pmatch[matches].rm_eo;
  20. pmatch[matches].rm_so += current;
  21. pmatch[matches].rm_eo += current;
  22. matches++;
  23. } else if (ret == REG_NOMATCH) {
  24. break;
  25. } else {
  26. break;
  27. }
  28. }
  29. return matches;
  30. }
  31. const char *clean_string(const char *badansi) {
  32. static char buffer[1024];
  33. char *cp;
  34. strcpy(buffer, badansi);
  35. cp = buffer;
  36. while ((cp = strstr(cp, "\x1b")) != NULL) {
  37. *cp = '~';
  38. };
  39. return buffer;
  40. }
  41. void test(const char *trythis) {
  42. regmatch_t regmatches[MAX_MATCH];
  43. int matches, x;
  44. const char *clean = clean_string(trythis);
  45. printf("TEST (%s)\n", clean);
  46. matches = regmatch(&regex, trythis, MAX_MATCH, regmatches, 0);
  47. if (matches == 0) {
  48. printf("No matches.\n");
  49. } else {
  50. printf("%d matches:\n", matches);
  51. for (x = 0; x < matches; x++) {
  52. printf("%d (%d - %d)\n", x, regmatches[x].rm_so, regmatches[x].rm_eo);
  53. printf(" %*s [%.*s]\n", regmatches[x].rm_so, "",
  54. regmatches[x].rm_eo - regmatches[x].rm_so,
  55. clean + regmatches[x].rm_so);
  56. }
  57. }
  58. }
  59. void test_(const char *trythis) {
  60. int ret;
  61. char msgbuf[100];
  62. const char *p = trythis;
  63. // safe printing (maybe)
  64. strcpy(msgbuf, trythis);
  65. char *fixup = msgbuf;
  66. while ((fixup = strstr(fixup, "\x1b")) != NULL) {
  67. *fixup = '^';
  68. };
  69. printf("Test: [%s]%s\n", msgbuf, RESET);
  70. regmatch_t matches[MAX_MATCH];
  71. while (1) {
  72. ret = regexec(&regex, p, MAX_MATCH, matches, 0);
  73. if (!ret) {
  74. printf("MATCH!\n");
  75. for (int i = 0; i < MAX_MATCH; i++) {
  76. int start, finish;
  77. if (matches[i].rm_so == -1)
  78. break;
  79. start = matches[i].rm_so;
  80. finish = matches[i].rm_eo;
  81. // %.*s = length to print, char * to use
  82. strncpy(msgbuf, p + start, (finish - start));
  83. msgbuf[finish - start] = 0;
  84. fixup = msgbuf;
  85. while ((fixup = strstr(fixup, "\x1b")) != NULL) {
  86. *fixup = '^';
  87. };
  88. // printf("'%.*s'%s %d : %d - %d\n", (finish - start), p + start, RESET,
  89. // i, start, finish);
  90. printf("'%s' %d : %d - %d\n", msgbuf, i, start, finish);
  91. };
  92. p += matches[0].rm_eo;
  93. } else if (ret == REG_NOMATCH) {
  94. printf("Sorry, no matches.\n");
  95. break;
  96. } else {
  97. regerror(ret, &regex, msgbuf, sizeof(msgbuf));
  98. fprintf(stderr, "Regex match failed: %s\n", msgbuf);
  99. }
  100. }
  101. return;
  102. }
  103. int main(int argc, char *argv[]) {
  104. // char RX[] = "(\x1b\[(?:\\d+|;)+[a-zA-Z])";
  105. // char RX[] = "([a-z][a-z]([0-9]+))";
  106. char RX[] = "([a-z][a-z]([0-9]+))";
  107. char msgbuf[100];
  108. int ret;
  109. if ((ret = regcomp(&regex, RX, REG_EXTENDED | REG_NEWLINE))) {
  110. regerror(ret, &regex, msgbuf, sizeof(msgbuf));
  111. fprintf(stderr, "Regex compile failed: %s\n", msgbuf);
  112. return 1;
  113. }
  114. test("this will fail.");
  115. test("this has ab5 ab55 zd3 three matches.");
  116. regfree(&regex);
  117. // if ( regcomp( &regex, "(\x1b\[(?:[0-9]|;)+[a-zA-Z])",
  118. // REG_EXTENDED|REG_NEWLINE ) ) { if ( regcomp( &regex,
  119. // "(\x1b\[([0-9]+|;)+[a-zA-Z])", REG_EXTENDED|REG_NEWLINE ) ) { if ( regcomp(
  120. // &regex, "\x1b\[[0-9]+(;[0-9]+)+?[a-zA-Z]", REG_EXTENDED|REG_NEWLINE ) ) {
  121. if (regcomp(&regex, "\x1b\[[0-9]+(;[0-9]+)*?[a-zA-Z]",
  122. REG_EXTENDED | REG_NEWLINE)) {
  123. regerror(ret, &regex, msgbuf, sizeof(msgbuf));
  124. fprintf(stderr, "Regex compile failed: %s\n", msgbuf);
  125. return 1;
  126. };
  127. test("\x1b[1;1H\x1b[2J\x0cMystic BBS\x1b[6n");
  128. test("\x1b[5;1HMEEP.");
  129. test("\x1b[0;1;34;47mHello");
  130. regfree(&regex);
  131. // \s matches space, FORM FEED. Ouch! NO!
  132. if (regcomp(&regex, "[a-zA-Z]+( [a-zA-Z]+)+", REG_EXTENDED | REG_NEWLINE)) {
  133. regerror(ret, &regex, msgbuf, sizeof(msgbuf));
  134. fprintf(stderr, "Regex compile failed: %s\n", msgbuf);
  135. return 1;
  136. };
  137. test("\x1b[1;1H\x1b[2J\x0cMystic BBS\x1b[6n");
  138. test("\x1b[5;1HMEEP is cool for cats.");
  139. regfree(&regex);
  140. return 0;
  141. }