Skip to content

Instantly share code, notes, and snippets.

@tanbro
Last active May 16, 2024 01:25
Show Gist options
  • Save tanbro/4379692 to your computer and use it in GitHub Desktop.
Save tanbro/4379692 to your computer and use it in GitHub Desktop.
str replace and regex replace functions in C language
#ifndef __RE_REPLACE__
#define __RE_REPLACE__
#include <string.h>
#include <regex.h>
#ifdef __cplusplus
extern "C" {
#endif
char* re_replace(const char *s, regex_t *buffer, const char *rep, char **pout,
size_t *pout_sz);
#ifdef __cplusplus
}
#endif
char* re_replace(const char *s, regex_t *buffer, const char *rep, char **pout,
size_t *pout_sz) {
int start = 0;
size_t s_len = strlen(s);
int range = s_len;
size_t rep_len = strlen(rep);
size_t out_sz = pout_sz ? (*pout_sz ? *pout_sz : 1) : 1;
char* out = NULL;
if (pout) {
if (*pout) {
*pout = (char*) realloc(*pout, out_sz * sizeof(char));
memset(*pout, 0, out_sz);
} else {
*pout = (char*) calloc(out_sz, sizeof(char));
}
out = *pout;
} else {
out = (char*) calloc(out_sz, sizeof(char));
}
struct re_registers regs;
while (true) {
memset(&regs, 0, sizeof(re_registers));
int res = re_search(buffer, s, s_len, start, range, &regs);
if (res == -1) {
if (out_sz - strlen(out) <= (size_t) range) {
out_sz += range;
out = (char*) realloc(out, out_sz);
memset(out + strlen(out), 0, range);
}
strncat(out + strlen(out), s + start, range);
break;
} else if (res == -2) {
fprintf(stderr, "re_search() returns -2 for an internal error.\n");
break;
} else {
unsigned i;
for (i = 0; i < regs.num_regs; i++) {
if (regs.start[i] == -1)
continue;
size_t append_sz = regs.start[i] - start + rep_len;
if (out_sz - strlen(out) <= append_sz) {
out_sz += append_sz;
out = (char*) realloc(out, out_sz);
memset(out + strlen(out), 0, append_sz);
}
strncat(out + strlen(out), s + start, regs.start[i] - start);
strncat(out + strlen(out), rep, rep_len);
start = regs.end[i];
range = s_len - regs.end[i];
}
}
}
if (pout_sz){
*pout_sz = out_sz;
}
if (pout){
*pout = out;
}
return out;
}
#endif
#ifndef __STR_REPLACE__
#define __STR_REPLACE__
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
int str_replace(const char *orig, const char *rep, const char *with,
char **pbuf, size_t *pbuf_sz);
#ifdef __cplusplus
}
#endif
int str_replace(const char *orig, const char *rep, const char *with,
char **pbuf, size_t *pbuf_sz) {
char *ins; // the next insert point
char *tmp; // varies
int len_rep; // length of rep
int len_with; // length of with
int len_front; // distance between rep and end of last rep
int count; // number of replacements
if (!orig)
return -2;
if (!rep || !(len_rep = strlen(rep)))
return -2;
if (!(ins = strstr(orig, rep)))
return -1;
if (!with)
return -2;
if (!pbuf)
return -2;
len_with = strlen(with);
for (count = 0; ((tmp = strstr(ins, rep)) != NULL); ++count) {
ins = tmp + len_rep;
}
size_t buf_sz = strlen(orig) + (len_with - len_rep) * count + 1;
if (pbuf_sz)
*pbuf_sz = buf_sz;
if (*pbuf) {
tmp = *pbuf = (char*) realloc(*pbuf, buf_sz);
memset(*pbuf, 0, buf_sz);
} else {
tmp = *pbuf = (char*) calloc(buf_sz, sizeof(char));
}
while (count--) {
ins = strstr(orig, rep);
len_front = ins - orig;
tmp = strncpy(tmp, orig, len_front) + len_front;
tmp = strcpy(tmp, with) + len_with;
orig += len_front + len_rep; // move to next "end of rep"
}
strcpy(tmp, orig);
return 0;
}
#endif
@ShikiSuen
Copy link

@tanbro Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment