diff options
Diffstat (limited to 'xs_regex.h')
| -rw-r--r-- | xs_regex.h | 34 |
1 files changed, 23 insertions, 11 deletions
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #define _XS_REGEX_H | 5 | #define _XS_REGEX_H |
| 6 | 6 | ||
| 7 | int xs_regex_match(const char *str, const char *rx); | ||
| 7 | xs_list *xs_regex_split_n(const char *str, const char *rx, int count); | 8 | xs_list *xs_regex_split_n(const char *str, const char *rx, int count); |
| 8 | #define xs_regex_split(str, rx) xs_regex_split_n(str, rx, XS_ALL) | 9 | #define xs_regex_split(str, rx) xs_regex_split_n(str, rx, XS_ALL) |
| 9 | xs_list *xs_regex_select_n(const char *str, const char *rx, int count); | 10 | xs_list *xs_regex_select_n(const char *str, const char *rx, int count); |
| @@ -18,18 +19,21 @@ xs_list *xs_regex_replace_in(xs_str *str, const char *rx, const char *rep, int c | |||
| 18 | #include <regex.h> | 19 | #include <regex.h> |
| 19 | 20 | ||
| 20 | xs_list *xs_regex_split_n(const char *str, const char *rx, int count) | 21 | xs_list *xs_regex_split_n(const char *str, const char *rx, int count) |
| 21 | /* splits str by regex */ | 22 | /* splits str using regex as a separator, at most count times. |
| 23 | Always returns a list: | ||
| 24 | len == 0: regcomp error | ||
| 25 | len == 1: full string (no matches) | ||
| 26 | len == odd: first part [ separator / next part ]... | ||
| 27 | */ | ||
| 22 | { | 28 | { |
| 23 | regex_t re; | 29 | regex_t re; |
| 24 | regmatch_t rm; | 30 | regmatch_t rm; |
| 25 | int offset = 0; | 31 | int offset = 0; |
| 26 | xs_list *list = NULL; | 32 | xs_list *list = xs_list_new(); |
| 27 | const char *p; | 33 | const char *p; |
| 28 | 34 | ||
| 29 | if (regcomp(&re, rx, REG_EXTENDED)) | 35 | if (regcomp(&re, rx, REG_EXTENDED)) |
| 30 | return NULL; | 36 | return list; |
| 31 | |||
| 32 | list = xs_list_new(); | ||
| 33 | 37 | ||
| 34 | while (count > 0 && !regexec(&re, (p = str + offset), 1, &rm, offset > 0 ? REG_NOTBOL : 0)) { | 38 | while (count > 0 && !regexec(&re, (p = str + offset), 1, &rm, offset > 0 ? REG_NOTBOL : 0)) { |
| 35 | /* add first the leading part of the string */ | 39 | /* add first the leading part of the string */ |
| @@ -60,16 +64,15 @@ xs_list *xs_regex_select_n(const char *str, const char *rx, int count) | |||
| 60 | { | 64 | { |
| 61 | xs_list *list = xs_list_new(); | 65 | xs_list *list = xs_list_new(); |
| 62 | xs *split = NULL; | 66 | xs *split = NULL; |
| 63 | xs_list *p; | ||
| 64 | xs_val *v; | 67 | xs_val *v; |
| 65 | int n = 0; | 68 | int n = 0; |
| 69 | int c = 0; | ||
| 66 | 70 | ||
| 67 | /* split */ | 71 | /* split */ |
| 68 | split = xs_regex_split_n(str, rx, count); | 72 | split = xs_regex_split_n(str, rx, count); |
| 69 | 73 | ||
| 70 | /* now iterate to get only the 'separators' (odd ones) */ | 74 | /* now iterate to get only the 'separators' (odd ones) */ |
| 71 | p = split; | 75 | while (xs_list_next(split, &v, &c)) { |
| 72 | while (xs_list_iter(&p, &v)) { | ||
| 73 | if (n & 0x1) | 76 | if (n & 0x1) |
| 74 | list = xs_list_append(list, v); | 77 | list = xs_list_append(list, v); |
| 75 | 78 | ||
| @@ -86,13 +89,12 @@ xs_list *xs_regex_replace_in(xs_str *str, const char *rx, const char *rep, int c | |||
| 86 | { | 89 | { |
| 87 | xs_str *s = xs_str_new(NULL); | 90 | xs_str *s = xs_str_new(NULL); |
| 88 | xs *split = xs_regex_split_n(str, rx, count); | 91 | xs *split = xs_regex_split_n(str, rx, count); |
| 89 | xs_list *p; | ||
| 90 | xs_val *v; | 92 | xs_val *v; |
| 91 | int n = 0; | 93 | int n = 0; |
| 94 | int c = 0; | ||
| 92 | int pholder = !!strchr(rep, '&'); | 95 | int pholder = !!strchr(rep, '&'); |
| 93 | 96 | ||
| 94 | p = split; | 97 | while (xs_list_next(split, &v, &c)) { |
| 95 | while (xs_list_iter(&p, &v)) { | ||
| 96 | if (n & 0x1) { | 98 | if (n & 0x1) { |
| 97 | if (pholder) { | 99 | if (pholder) { |
| 98 | /* rep has a placeholder; process char by char */ | 100 | /* rep has a placeholder; process char by char */ |
| @@ -128,6 +130,16 @@ xs_list *xs_regex_replace_in(xs_str *str, const char *rx, const char *rep, int c | |||
| 128 | return s; | 130 | return s; |
| 129 | } | 131 | } |
| 130 | 132 | ||
| 133 | |||
| 134 | int xs_regex_match(const char *str, const char *rx) | ||
| 135 | /* returns if str matches the regex at least once */ | ||
| 136 | { | ||
| 137 | xs *l = xs_regex_select_n(str, rx, 1); | ||
| 138 | |||
| 139 | return xs_list_len(l) == 1; | ||
| 140 | } | ||
| 141 | |||
| 142 | |||
| 131 | #endif /* XS_IMPLEMENTATION */ | 143 | #endif /* XS_IMPLEMENTATION */ |
| 132 | 144 | ||
| 133 | #endif /* XS_REGEX_H */ | 145 | #endif /* XS_REGEX_H */ |