Replace using POSIX regular expressions
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <regex.h>
#include <string.h>
int rmatch(const char *string, char *pattern) {
int status;
regex_t re;
if (regcomp(&re, pattern, REG_EXTENDED | REG_NOSUB) != 0) {
return 0;
}
status = regexec(&re, string, (size_t) 0, NULL, 0);
regfree(&re);
if (status != 0) {
return 0;
}
return 1;
}
int __rreplace(char *buf, int size, regex_t *re, char *rp) {
char *pos;
int sub, so, n;
regmatch_t pmatch[10]; /* regoff_t is int so size is int */
if (regexec(re, buf, 10, pmatch, 0))
return 0;
for (pos = rp; *pos; pos++)
if (*pos == '\\' && *(pos + 1) > '0' && *(pos + 1) <= '9') {
so = pmatch[*(pos + 1) - 48].rm_so;
n = pmatch[*(pos + 1) - 48].rm_eo - so;
if (so < 0 || strlen(rp) + n - 1 > size)
return 1;
memmove(pos + n, pos + 2, strlen(pos) - 1);
memmove(pos, buf + so, n);
pos = pos + n - 2;
}
sub = pmatch[1].rm_so; /* no repeated replace when sub >= 0 */
for (pos = buf; !regexec(re, pos, 1, pmatch, 0);) {
n = pmatch[0].rm_eo - pmatch[0].rm_so;
pos += pmatch[0].rm_so;
if (strlen(buf) - n + strlen(rp) + 1 > size)
return 1;
memmove(pos + strlen(rp), pos + n, strlen(pos) - n + 1);
memmove(pos, rp, strlen(rp));
pos += strlen(rp);
if (sub >= 0)
break;
}
return 0;
}
int rreplace(char *buf, int size, char *expressions, char *rp) {
int result;
regex_t re;
regcomp (&re, expressions, REG_ICASE);
result = __rreplace(buf, size, &re, rp);
regfree (&re);
return result;
}
int main(void) {
// match
printf("%s\r\n", rmatch("Hello World!", "^Hello.*!$") == 1 ? "true":"false");
// replace
int buf_size = 4096;
char buf [buf_size];
strcpy(buf, "hello world!");
rreplace(buf, buf_size, "world", "Jack");
printf("%s\r\n", buf);
return EXIT_SUCCESS;
}
沒有留言:
張貼留言