From 9a9b6b2b7b7931bf9ad301ba34aa53c341ec2505 Mon Sep 17 00:00:00 2001 From: Tyge Løvset Date: Tue, 2 Aug 2022 17:09:13 +0200 Subject: Improved the cregex_iter type and c_foreach_match() macro. --- examples/regex2.c | 31 +++++++++++++++---------------- examples/regex_match.c | 43 ++++++++++++++++++++----------------------- include/stc/cregex.h | 23 +++++++++++++---------- 3 files changed, 48 insertions(+), 49 deletions(-) diff --git a/examples/regex2.c b/examples/regex2.c index 257cdc1e..672020f6 100644 --- a/examples/regex2.c +++ b/examples/regex2.c @@ -1,34 +1,33 @@ #define i_implement #include -#include #include int main() { struct { const char *pattern, *input; } s[] = { {"(\\d\\d\\d\\d)[-_](1[0-2]|0[1-9])[-_](3[01]|[12][0-9]|0[1-9])", - "date: 2024-02-29 leapyear day, christmas eve is on 2022-12-24."}, + "date: 2024-02-29 leapyear day, christmas eve is on 2022-12-24." + }, {"(https?://|ftp://|www\\.)([0-9A-Za-z@:%_+~#=-]+\\.)+([a-z][a-z][a-z]?)(/[/0-9A-Za-z\\.@:%_+~#=\\?&-]*)?", - "https://en.cppreference.com/w/cpp/regex/regex_search"}, + "https://en.cppreference.com/w/cpp/regex/regex_search" + }, {"!((abc|123)+)!", "!123abcabc!"} }; + c_auto (cregex, re) c_forrange (i, c_arraylen(s)) { - c_auto (cregex, re) - { - int res = cregex_compile(&re, s[i].pattern, 0); - if (res < 0) { - printf("error in regex pattern: %d\n", res); - continue; - } - printf("input: %s\n", s[i].input); + int res = cregex_compile(&re, s[i].pattern, 0); + if (res < 0) { + printf("error in regex pattern: %d\n", res); + continue; + } + printf("input: %s\n", s[i].input); - c_foreach_match (m, &re, s[i].input) { - c_forrange (int, j, cregex_captures(&re)) - printf(" submatch %d: %.*s\n", j, c_ARGsv(m[j])); - puts(""); - } + c_foreach_match (j, &re, s[i].input) { + c_forrange (k, cregex_captures(&re)) + printf(" submatch %d: %.*s\n", k, c_ARGsv(j.ref[k])); + puts(""); } } } diff --git a/examples/regex_match.c b/examples/regex_match.c index 72039fde..1e87affb 100644 --- a/examples/regex_match.c +++ b/examples/regex_match.c @@ -1,38 +1,35 @@ #define i_implement #include #include +#define i_val float +#include int main() { // Lets find the first sequence of digits in a string - const char *s = "Hello numeric world, there are 24 hours in a day, 3600 seconds in an hour." - " Around 365.25 days a year, and 52 weeks in a year." - " Boltzmann const: 1.38064852E-23, is very small." - " Bohrradius is 5.29177210903e-11, and Avogadros number is 6.02214076e23."; + const char *str = "Hello numeric world, there are 24 hours in a day, 3600 seconds in an hour." + " Around 365.25 days a year, and 52 weeks in a year." + " Boltzmann const: 1.38064852E-23, is very small." + " Bohrradius is 5.29177210903e-11, and Avogadros number is 6.02214076e23."; c_auto (cregex, re) + c_auto (cstack_float, vec) + c_auto (cstr, nums) { - int res = cregex_compile(&re, "[+-]?([0-9]*\\.)?\\d+([Ee][+-]?\\d+)?", 0); - printf("%d\n", res); - csview m[5]; - if (cregex_find(s, &re, m, 0) == 1) { - printf("Found digits at position %" PRIuMAX "-%" PRIuMAX "\n", m[0].str - s, m[0].str - s + m[0].size); - } else { - printf("Could not find any digits\n"); - } + const char* pattern = "[+-]?([0-9]*\\.)?\\d+([Ee][+-]?\\d+)?"; + int res = cregex_compile(&re, pattern, 0); + printf("%d: %s\n", res, pattern); - while (cregex_find(s, &re, m, cre_m_next) == 1) { - printf("%.*s ; ", c_ARGsv(m[0])); - } - puts(""); + // extract and convert all numbers in str to floats + c_foreach_match (i, &re, str) + cstack_float_push(&vec, atof(i.ref->str)); - res = cregex_compile(&re, "(.+)\\b(.+)", 0); - printf("groups: %d\n", res); - if ((res = cregex_find("hello@wørld", &re, m, 0)) == 1) { - c_forrange (i, res) - printf("match: [%.*s]\n", c_ARGsv(m[i])); - } else - printf("err: %d\n", res); + c_foreach (i, cstack_float, vec) + 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); + printf("\n%s\n", cstr_str(&nums)); } } diff --git a/include/stc/cregex.h b/include/stc/cregex.h index fbf5b931..653b0b07 100644 --- a/include/stc/cregex.h +++ b/include/stc/cregex.h @@ -70,16 +70,19 @@ typedef struct { int error; } cregex; -#define c_foreach_match(m, re, input) \ - for (csview m[cre_MAXCAPTURES] = {{0}}, _c_in = csview_from(input); \ - cregex_find(_c_in.str, re, m, cre_m_next) == cre_success; ) - -//typedef csview cregmatch; +typedef struct { + const cregex* re; + const char* input; + csview ref[cre_MAXCAPTURES]; +} cregex_iter; + +#define c_foreach_match(i, _re, _input) \ + for (cregex_iter i = {_re, _input}; cregex_find(i.input, i.re, i.ref, cre_m_next) == cre_success;) static inline cregex cregex_init(void) { - cregex rx = {0}; - return rx; + cregex re = {0}; + return re; } /* return 1 on success, or negative error code on failure. */ @@ -87,9 +90,9 @@ int cregex_compile(cregex *self, const char* pattern, int cflags); static inline cregex cregex_from(const char* pattern, int cflags) { - cregex rx = {0}; - cregex_compile(&rx, pattern, cflags); - return rx; + cregex re = {0}; + cregex_compile(&re, pattern, cflags); + return re; } /* number of capture groups in a regex pattern, 0 if regex is invalid */ -- cgit v1.2.3