Last active
May 16, 2024 01:25
-
-
Save tanbro/4379692 to your computer and use it in GitHub Desktop.
str replace and regex replace functions in C language
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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(®s, 0, sizeof(re_registers)); | |
int res = re_search(buffer, s, s_len, start, range, ®s); | |
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@ShikiSuen 感谢关注。
这是很多年前的一段代码了……我想,也许我们把它视作 MIT License 会比较友好。