regex-capture iterate

This commit is contained in:
John Kerl 2016-01-14 23:17:53 -05:00
parent 1ac3fa1a15
commit da6aca5443
5 changed files with 101 additions and 35 deletions

View file

@ -117,6 +117,7 @@ TEST_MLRUTIL_SRCS = \
lib/mlr_globals.c \
lib/mlrutil.c \
lib/string_builder.c \
lib/string_array.c \
unit_test/test_mlrutil.c
TEST_STRING_BUILDER_SRCS = \

View file

@ -546,7 +546,7 @@ char* regex_gsub(char* input, regex_t* pregex, string_builder_t* psb, char* repl
char* p = replacement;
int len1 = psb->used_length;
while (*p) {
if (p[0] == '\\' && isdigit(p[1])) {
if (p[0] == '\\' && isdigit(p[1]) && p[1] != '0') {
int idx = p[1] - '0';
regmatch_t* pmatch = &matches[idx];
if (pmatch->rm_so == -1) {
@ -574,3 +574,39 @@ char* regex_gsub(char* input, regex_t* pregex, string_builder_t* psb, char* repl
match_start += matches[0].rm_so + replen;
}
}
// ----------------------------------------------------------------
char* interpolate_regex_captures(char* input, string_array_t* pregex_captures, int* pwas_allocated) {
*pwas_allocated = FALSE;
if (pregex_captures == NULL || pregex_captures->length == 0)
return input;
string_builder_t* psb = sb_alloc(32);
char* p = input;
while (*p) {
if (p[0] == '\\' && isdigit(p[1]) && p[1] != '0') {
int idx = p[1] - '0' - 1;
if (idx < pregex_captures->length) {
*pwas_allocated = TRUE;
sb_append_string(psb, pregex_captures->strings[idx]);
} else {
sb_append_char(psb, p[0]);
sb_append_char(psb, p[1]);
}
p += 2;
} else {
sb_append_char(psb, *p);
p++;
}
}
if (*pwas_allocated) {
char* output = sb_finish(psb);
sb_free(psb);
return output;
} else {
sb_free(psb);
return input;
}
}

View file

@ -7,6 +7,7 @@
#include <time.h>
#include <regex.h>
#include "string_builder.h"
#include "string_array.h"
#define TRUE 1
#define FALSE 0
@ -148,4 +149,6 @@ char* regex_sub(char* input, regex_t* pregex, string_builder_t* psb, char* repla
char* regex_gsub(char* input, regex_t* pregex, string_builder_t* psb, char* replacement, int* pmatched, int* pall_captured, unsigned char *pfree_flags);
char* interpolate_regex_captures(char* input, string_array_t* pregex_captures, int* pwas_allocated);
#endif // MLRUTIL_H

View file

@ -1288,40 +1288,6 @@ typedef struct _lrec_evaluator_literal_state_t {
// xxx put this in lib dir
//char* interpolate_regex_captures(char* input, string_array_t* pregex_captures, int* pwas_allocated) {
// *pwas_allocated = FALSE;
// if (pregex_captures == NULL || pregex_captures->length == 0)
// return input;
// string_builder_t* psb = sb_alloc(MV_SB_ALLOC_LENGTH);
//
// char* p = input;
// while (*p) {
// if (p[0] == '\\' && isdigit(p[1])) {
// int idx = p[1] - '0';
// if (idx < pregex_captures->length) {
// *pwas_allocated = TRUE;
// sb_append_string(psb, pregex_captures->strings[i]);
// } else {
// sb_append_char(psb, p[0]);
// sb_append_char(psb, p[1]);
// }
// p += 2;
// } else {
// sb_append_char(psb, *p);
// p++;
// }
// }
//
// if (*pwas_allocated) {
// char* output = sb_finish(psb);
// sb_free(psb);
// return output;
// } else {
// sb_free(psb);
// return input;
// }
//}
mv_t lrec_evaluator_non_string_literal_func(lrec_t* prec, lhmsv_t* ptyped_overlay, string_array_t* pregex_captures,
context_t* pctx, void* pvstate)
{

View file

@ -142,6 +142,65 @@ static char * test_unbackslash() {
return 0;
}
// ----------------------------------------------------------------
static char * test_interpolate_regex_captures() {
int was_allocated = FALSE;
char* output = interpolate_regex_captures("hello", NULL, &was_allocated);
mu_assert_lf(streq(output, "hello"));
mu_assert_lf(was_allocated == FALSE);
string_array_t* psa = string_array_alloc(0);
output = interpolate_regex_captures("hello", psa, &was_allocated);
mu_assert_lf(streq(output, "hello"));
mu_assert_lf(was_allocated == FALSE);
string_array_free(psa);
psa = string_array_from_line(mlr_strdup_or_die("a,b,c"), ',');
output = interpolate_regex_captures("hello", psa, &was_allocated);
mu_assert_lf(streq(output, "hello"));
mu_assert_lf(was_allocated == FALSE);
string_array_free(psa);
psa = string_array_from_line(mlr_strdup_or_die("a,b,c"), ',');
output = interpolate_regex_captures("h\\3ello", psa, &was_allocated);
printf("output=[%s]\n", output);
mu_assert_lf(streq(output, "hcello"));
mu_assert_lf(was_allocated == TRUE);
string_array_free(psa);
psa = string_array_from_line(mlr_strdup_or_die("a,b,c"), ',');
output = interpolate_regex_captures("h\\1ello", psa, &was_allocated);
printf("output=[%s]\n", output);
mu_assert_lf(streq(output, "haello"));
mu_assert_lf(was_allocated == TRUE);
string_array_free(psa);
psa = string_array_from_line(mlr_strdup_or_die("a,b,c"), ',');
output = interpolate_regex_captures("h\\4ello", psa, &was_allocated);
printf("output=[%s]\n", output);
mu_assert_lf(streq(output, "h\\4ello"));
mu_assert_lf(was_allocated == FALSE);
string_array_free(psa);
psa = string_array_from_line(mlr_strdup_or_die("a,b,c"), ',');
output = interpolate_regex_captures("h\\0ello", psa, &was_allocated);
printf("output=[%s]\n", output);
mu_assert_lf(streq(output, "h\\0ello"));
mu_assert_lf(was_allocated == FALSE);
string_array_free(psa);
psa = string_array_from_line(mlr_strdup_or_die("a,b,c"), ',');
output = interpolate_regex_captures("h\\3e\\1l\\2l\\4o", psa, &was_allocated);
printf("output=[%s]\n", output);
mu_assert_lf(streq(output, "hcealbl\\4o"));
mu_assert_lf(was_allocated == TRUE);
string_array_free(psa);
return 0;
}
// ================================================================
static char * all_tests() {
mu_run_test(test_canonical_mod);
@ -151,6 +210,7 @@ static char * all_tests() {
mu_run_test(test_scanners);
mu_run_test(test_paste);
mu_run_test(test_unbackslash);
mu_run_test(test_interpolate_regex_captures);
return 0;
}