Skip to content

Commit

Permalink
Populate captures also for zero-width matches
Browse files Browse the repository at this point in the history
Instead of just using {"captures":[]}.

sub functions are use captures for replacement expressions.
If we don't populate, captures for empty matches, the replacement
expression is run with an empty object as input instead of an object
containing the named captures with "" as value:

* before:

  $ jq -n '"123foo456bar" | gsub("[^a-z]*(?<x>[a-z]*)"; "Z\(.x)")'
  "ZfooZbarZnull"

* after:

  $ jq -n '"123foo456bar" | gsub("[^a-z]*(?<x>[a-z]*)"; "Z\(.x)")'
  "ZfooZbarZ"

---

I also removed a redundant

  result = NULL;
  if (result) {
    ...
  }
  • Loading branch information
emanuele6 committed Jul 18, 2023
1 parent b382867 commit 30bb214
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 4 deletions.
14 changes: 11 additions & 3 deletions src/builtin.c
Original file line number Diff line number Diff line change
Expand Up @@ -931,7 +931,17 @@ static jv f_match(jq_state *jq, jv input, jv regex, jv modifiers, jv testmode) {
jv match = jv_object_set(jv_object(), jv_string("offset"), jv_number(idx));
match = jv_object_set(match, jv_string("length"), jv_number(0));
match = jv_object_set(match, jv_string("string"), jv_string(""));
match = jv_object_set(match, jv_string("captures"), jv_array());
jv captures = jv_array();
for (int i = 1; i < region->num_regs; ++i) {
jv cap = jv_object();
cap = jv_object_set(cap, jv_string("offset"), jv_number(idx));
cap = jv_object_set(cap, jv_string("string"), jv_string(""));
cap = jv_object_set(cap, jv_string("length"), jv_number(0));
cap = jv_object_set(cap, jv_string("name"), jv_null());
captures = jv_array_append(captures, cap);
}
onig_foreach_name(reg, f_match_name_iter, &captures);
match = jv_object_set(match, jv_string("captures"), captures);
result = jv_array_append(result, match);
// ensure '"qux" | match("(?=u)"; "g")' matches just once
start = (const UChar*)(input_string+region->end[0]+1);
Expand Down Expand Up @@ -1005,8 +1015,6 @@ static jv f_match(jq_state *jq, jv input, jv regex, jv modifiers, jv testmode) {
} while (global && start <= end);
onig_region_free(region,1);
region = NULL;
if (region)
onig_region_free(region,1);
onig_free(reg);
jv_free(input);
jv_free(regex);
Expand Down
6 changes: 5 additions & 1 deletion tests/onig.test
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# match builtin
[match("( )*"; "g")]
"abc"
[{"offset":0, "length":0, "string":"", "captures":[]}, {"offset":1, "length":0, "string":"", "captures":[]}, {"offset":2, "length":0, "string":"", "captures":[]}, {"offset":3, "length":0, "string":"", "captures":[]}]
[{"offset":0,"length":0,"string":"","captures":[{"offset":0,"string":"","length":0,"name":null}]},{"offset":1,"length":0,"string":"","captures":[{"offset":1,"string":"","length":0,"name":null}]},{"offset":2,"length":0,"string":"","captures":[{"offset":2,"string":"","length":0,"name":null}]},{"offset":3,"length":0,"string":"","captures":[{"offset":3,"string":"","length":0,"name":null}]}]

[match("( )*"; "gn")]
"abc"
Expand Down Expand Up @@ -145,6 +145,10 @@ gsub("\\b(?<x>.)"; "\(.x|ascii_downcase)")
"ABC DEF"
"aBC dEF"

gsub("[^a-z]*(?<x>[a-z]*)"; "Z\(.x)")
"123foo456bar"
"ZfooZbarZ"

# utf-8
sub("(?<x>.)"; "\(.x)!")
"’"
Expand Down

0 comments on commit 30bb214

Please sign in to comment.