diff options
| -rw-r--r-- | docs/cregex_api.md | 29 | ||||
| -rw-r--r-- | examples/regex1.c | 2 | ||||
| -rw-r--r-- | examples/regex_match.c | 3 | ||||
| -rw-r--r-- | examples/regex_replace.c | 13 | ||||
| -rw-r--r-- | include/stc/cregex.h | 33 | ||||
| -rw-r--r-- | src/cregex.c | 37 |
6 files changed, 58 insertions, 59 deletions
diff --git a/docs/cregex_api.md b/docs/cregex_api.md index 87e25e02..6fd5ba1d 100644 --- a/docs/cregex_api.md +++ b/docs/cregex_api.md @@ -32,20 +32,17 @@ int cregex_compile(cregex *self, const char* pattern, int cflags); int cregex_captures(const cregex* self); // return 1=match, 0=nomatch, -1=error. match array size: at least num groups in RE (1+). -int cregex_find(const char* input, const cregex* re, csview match[], int mflags); -int cregex_find_sv(csview input, const cregex* re, csview match[]); - // takes string pattern instead of re. (for one-time matches) -int cregex_find_pt(const char* input, const char* pattern, csview match[], int cmflags); +int cregex_find(const cregex* re, const char* input, csview match[], int mflags); +int cregex_find_sv(const cregex* re, csview input, csview match[]); +int cregex_find_pattern(const char* pattern, const char* input, csview match[], int cmflags); -bool cregex_is_match(const char* input, const cregex* re); +bool cregex_is_match(const cregex* re, const char* input); -cstr cregex_replace(const char* input, const cregex* re, const char* replace, unsigned count); -cstr cregex_replace_ex(const char* input, const cregex* re, const char* replace, unsigned count, - int rflags, bool (*mfun)(int grp, csview match, cstr* mstr)); - // takes string pattern instead of re -cstr cregex_replace_pt(const char* input, const char* pattern, const char* replace, unsigned count); -cstr cregex_replace_pe(const char* input, const char* pattern, const char* replace, unsigned count, - int crflags, bool (*mfun)(int grp, csview match, cstr* mstr)); +cstr cregex_replace(const cregex* re, const char* input, const char* replace, unsigned count); +cstr cregex_replace_sv(const cregex* re, csview input, const char* replace, unsigned count, + int rflags, bool(*mfun)(int capgrp, csview match, cstr* mstr)); +cstr cregex_replace_pattern(const char* pattern, const char* input, const char* replace, unsigned count, + int rflags, bool(*mfun)(int capgrp, csview match, cstr* mstr)); void cregex_drop(cregex* self); // destroy ``` @@ -101,13 +98,13 @@ int main() { // Lets find the first date in the string: csview match[4]; // full-match, year, month, date. - if (cregex_find(input, &re, match, 0) == cre_success) + if (cregex_find(&re, input, match, 0) == cre_success) printf("Found date: %.*s\n", c_ARGsv(match[0])); else printf("Could not find any date\n"); // Lets change all dates into US date format MM/DD/YYYY: - cstr us_input = cregex_replace(input, &re, "$2/$3/$1"); + cstr us_input = cregex_replace(&re, input, "$2/$3/$1"); printf("US input: %s\n", cstr_str(&us_input)); // Free allocated data @@ -118,7 +115,7 @@ int main() { For a single match you may use the all-in-one function: ```c -if (cregex_find_pt(input, pattern, match, 0)) +if (cregex_find_pattern(pattern, input, match, 0)) printf("Found date: %.*s\n", c_ARGsv(match[0])); ``` @@ -130,7 +127,7 @@ In order to use a callback function in the replace call, see `examples/regex_rep To iterate multiple matches in an input string, you may use: ```c csview match[5] = {0}; -while (cregex_find(input, &re, match, cre_m_next) == cre_success) +while (cregex_find(&re, input, match, cre_m_next) == cre_success) c_forrange (int, k, cregex_captures(&re)) printf("submatch %d: %.*s\n", k, c_ARGsv(match[k])); ``` diff --git a/examples/regex1.c b/examples/regex1.c index c8b3a4f5..56ba8f1d 100644 --- a/examples/regex1.c +++ b/examples/regex1.c @@ -22,7 +22,7 @@ int main(int argc, char* argv[]) if (cstr_equals(&input, "q")) break; - if (cregex_is_match(cstr_str(&input), &float_expr)) + if (cregex_is_match(&float_expr, cstr_str(&input))) printf("Input is a float\n"); else printf("Invalid input : Not a float\n"); diff --git a/examples/regex_match.c b/examples/regex_match.c index 1e463104..78af5c77 100644 --- a/examples/regex_match.c +++ b/examples/regex_match.c @@ -1,5 +1,6 @@ #define i_implement #include <stc/cstr.h> +#include <stc/csview.h> #include <stc/cregex.h> #define i_val float #include <stc/cstack.h> @@ -28,7 +29,7 @@ int main() printf(" %g\n", *i.ref); // extracts the numbers only to a comma separated string. - nums = cregex_replace_ex(str, &re, " $0,", 0, cre_r_strip, NULL); + nums = cregex_replace_sv(&re, csview_from(str), " $0,", 0, cre_r_strip, NULL); printf("\n%s\n", cstr_str(&nums)); } } diff --git a/examples/regex_replace.c b/examples/regex_replace.c index 8640ced1..6464198c 100644 --- a/examples/regex_replace.c +++ b/examples/regex_replace.c @@ -1,5 +1,6 @@ #define i_implement #include <stc/cstr.h> +#include <stc/csview.h> #include <stc/cregex.h> bool add_10_years(int i, csview m, cstr* mstr) { @@ -22,15 +23,15 @@ int main() printf("INPUT: %s\n", input); /* replace with a fixed string, extended all-in-one call: */ - cstr_take(&str, cregex_replace_pt(input, pattern, "YYYY-MM-DD", 0)); + cstr_take(&str, cregex_replace_pattern(pattern, input, "YYYY-MM-DD", 0, 0, NULL)); printf("fixed: %s\n", cstr_str(&str)); /* US date format, and add 10 years to dates: */ - cstr_take(&str, cregex_replace_pe(input, pattern, "$1/$3/$2", 0, 0, add_10_years)); + cstr_take(&str, cregex_replace_pattern(pattern, input, "$1/$3/$2", 0, 0, add_10_years)); printf("us+10: %s\n", cstr_str(&str)); /* Wrap first date inside []: */ - cstr_take(&str, cregex_replace_pt(input, pattern, "[$0]", 1)); + cstr_take(&str, cregex_replace_pattern(pattern, input, "[$0]", 1, 0, NULL)); printf("brack: %s\n", cstr_str(&str)); /* Shows how to compile RE separately */ @@ -38,16 +39,16 @@ int main() if (cregex_captures(&re) == 0) continue; // break c_with /* European date format. */ - cstr_take(&str, cregex_replace(input, &re, "$3.$2.$1", 0)); + cstr_take(&str, cregex_replace(&re, input, "$3.$2.$1", 0)); printf("euros: %s\n", cstr_str(&str)); /* Strip out everything but the matches */ - cstr_take(&str, cregex_replace_ex(input, &re, "$3.$2.$1;", 0, cre_r_strip, NULL)); + cstr_take(&str, cregex_replace_sv(&re, csview_from(input), "$3.$2.$1;", 0, cre_r_strip, NULL)); printf("strip: %s\n", cstr_str(&str)); } /* Wrap all words in ${} */ - cstr_take(&str, cregex_replace_pt("[52] apples and [31] mangoes", "[a-z]+", "$${$0}", 0)); + cstr_take(&str, cregex_replace_pattern("[a-z]+", "52 apples and 31 mangoes", "$${$0}", 0, 0, NULL)); printf("curly: %s\n", cstr_str(&str)); } } diff --git a/include/stc/cregex.h b/include/stc/cregex.h index f0dd13aa..17c3ec61 100644 --- a/include/stc/cregex.h +++ b/include/stc/cregex.h @@ -78,7 +78,7 @@ typedef struct { #define c_foreach_match(it, Re, Input) \ for (cregex_iter it = {Re, Input}; \ - cregex_find(it.input, it.re, it.match, cre_m_next) == cre_success;) + cregex_find(it.re, it.input, it.match, cre_m_next) == cre_success;) static inline cregex cregex_init(void) { @@ -100,36 +100,35 @@ cregex cregex_from(const char* pattern, int cflags) { int cregex_captures(const cregex* self); /* return 1 on match, 0 on nomatch, and -1 on failure. */ -int cregex_find(const char* input, const cregex* re, +int cregex_find(const cregex* re, const char* input, csview match[], int mflags); static inline -int cregex_find_sv(csview input, const cregex* re, csview match[]) { +int cregex_find_sv(const cregex* re, csview input, csview match[]) { match[0] = input; - return cregex_find(input.str, re, match, cre_m_startend); + return cregex_find(re, input.str, match, cre_m_startend); } /* match + compile RE pattern */ -int cregex_find_pt(const char* input, const char* pattern, - csview match[], int cmflags); +int cregex_find_pattern(const char* pattern, const char* input, + csview match[], int cmflags); static inline -bool cregex_is_match(const char* input, const cregex* re) - { return cregex_find(input, re, NULL, 0) == cre_success; } +bool cregex_is_match(const cregex* re, const char* input) + { return cregex_find(re, input, NULL, 0) == cre_success; } /* replace regular expression */ -cstr cregex_replace_ex(const char* input, const cregex* re, const char* replace, unsigned count, +cstr cregex_replace_sv(const cregex* re, csview input, const char* replace, unsigned count, int rflags, bool (*mfun)(int i, csview match, cstr* mstr)); -static inline -cstr cregex_replace(const char* input, const cregex* re, const char* replace, unsigned count) - { return cregex_replace_ex(input, re, replace, count, 0, NULL); } -/* replace + compile RE pattern, and extra arguments */ -cstr cregex_replace_pe(const char* input, const char* pattern, const char* replace, unsigned count, - int crflags, bool (*mfun)(int i, csview match, cstr* mstr)); static inline -cstr cregex_replace_pt(const char* input, const char* pattern, const char* replace, unsigned count) - { return cregex_replace_pe(input, pattern, replace, count, 0, NULL); } +cstr cregex_replace(const cregex* re, const char* input, const char* replace, unsigned count) { + csview sv = {input, strlen(input)}; + return cregex_replace_sv(re, sv, replace, count, 0, NULL); +} +/* replace + compile RE pattern, and extra arguments */ +cstr cregex_replace_pattern(const char* pattern, const char* input, const char* replace, unsigned count, + int crflags, bool (*mfun)(int i, csview match, cstr* mstr)); /* destroy regex */ void cregex_drop(cregex* self); diff --git a/src/cregex.c b/src/cregex.c index 46d4d323..61e938d8 100644 --- a/src/cregex.c +++ b/src/cregex.c @@ -1153,7 +1153,7 @@ regexec(const Reprog *progp, /* program to run */ static void build_subst_string(const char* replace, unsigned nmatch, const csview match[], - bool (*mfun)(int i, csview match, cstr* mstr), cstr* subst) { + bool (*mfun)(int, csview, cstr*), cstr* subst) { cstr_buf buf = cstr_buffer(subst); unsigned len = 0, cap = buf.cap; char* dst = buf.data; @@ -1208,7 +1208,7 @@ cregex_captures(const cregex* self) { } int -cregex_find(const char* input, const cregex* re, +cregex_find(const cregex* re, const char* input, csview match[], int mflags) { int res = regexec(re->prog, input, cregex_captures(re), match, mflags); switch (res) { @@ -1218,47 +1218,48 @@ cregex_find(const char* input, const cregex* re, } } -int cregex_find_pt(const char* input, const char* pattern, - csview match[], int cmflags) { +int +cregex_find_pattern(const char* pattern, const char* input, + csview match[], int cmflags) { cregex re = cregex_init(); int res = cregex_compile(&re, pattern, cmflags); if (res != cre_success) return res; - res = cregex_find(input, &re, match, cmflags); + res = cregex_find(&re, input, match, cmflags); cregex_drop(&re); return res; } cstr -cregex_replace_ex(const char* input, const cregex* re, const char* replace, unsigned count, - int rflags, bool (*mfun)(int i, csview match, cstr* mstr)) { +cregex_replace_sv(const cregex* re, csview input, const char* replace, unsigned count, + int rflags, bool (*mfun)(int, csview, cstr*)) { cstr out = cstr_null; cstr subst = cstr_null; - size_t from = 0; csview match[cre_MAXCAPTURES]; unsigned nmatch = cregex_captures(re); if (!count) count = ~0; bool copy = !(rflags & cre_r_strip); - while (count-- && cregex_find(input + from, re, match, 0) == cre_success) { + while (count-- && cregex_find_sv(re, input, match) == cre_success) { build_subst_string(replace, nmatch, match, mfun, &subst); - const size_t pos = match[0].str - input; - if (copy) cstr_append_n(&out, input + from, pos - from); + const size_t mpos = match[0].str - input.str; + if (copy & (mpos > 0)) cstr_append_n(&out, input.str, mpos); cstr_append_s(&out, subst); - from = pos + match[0].size; + input.str = match[0].str + match[0].size; + input.size -= mpos + match[0].size; } - if (copy) cstr_append(&out, input + from); + if (copy) cstr_append_sv(&out, input); cstr_drop(&subst); return out; } cstr -cregex_replace_pe(const char* input, const char* pattern, const char* replace, unsigned count, - int crflags, bool (*mfun)(int i, csview match, cstr* mstr)) { +cregex_replace_pattern(const char* pattern, const char* input, const char* replace, unsigned count, + int crflags, bool (*mfun)(int, csview, cstr*)) { cregex re = cregex_init(); - int res = cregex_compile(&re, pattern, crflags); - if (res != cre_success) + if (cregex_compile(&re, pattern, crflags) != cre_success) return cstr_new("[[error: invalid regex pattern]]"); - cstr out = cregex_replace_ex(input, &re, replace, count, crflags, mfun); + csview sv = {input, strlen(input)}; + cstr out = cregex_replace_sv(&re, sv, replace, count, crflags, mfun); cregex_drop(&re); return out; } |
