try-re.c 4.7 KB

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