diff --git a/lib/resty/core/regex.lua b/lib/resty/core/regex.lua index 336f387c1..b5a3e7d19 100644 --- a/lib/resty/core/regex.lua +++ b/lib/resty/core/regex.lua @@ -244,7 +244,7 @@ local function destroy_compiled_regex(compiled) end -local function re_match_helper(subj, regex, opts, ctx, want_caps, res) +local function re_match_helper(subj, regex, opts, ctx, want_caps, res, nth) local flags = 0 local pcre_opts = 0 local pos @@ -347,7 +347,20 @@ local function re_match_helper(subj, regex, opts, ctx, want_caps, res) end if not want_caps then - return compiled.captures[0] + 1, compiled.captures[1] + if not nth or nth < 0 then + nth = 0 + end + + if nth <= compiled.ncaptures then + local from = compiled.captures[nth * 2] + 1 + local to = compiled.captures[nth * 2 + 1] + if from < 0 or to < 0 then + return nil, nil + end + return from, to + end + + return nil, nil, "nth out of bound" end res = collect_captures(compiled, rc, subj, flags, res) @@ -365,8 +378,8 @@ function ngx.re.match(subj, regex, opts, ctx, res) end -function ngx.re.find(subj, regex, opts, ctx) - return re_match_helper(subj, regex, opts, ctx, false) +function ngx.re.find(subj, regex, opts, ctx, nth) + return re_match_helper(subj, regex, opts, ctx, false, nil, nth) end diff --git a/t/re-find.t b/t/re-find.t index f9984619c..91a0b450c 100644 --- a/t/re-find.t +++ b/t/re-find.t @@ -9,7 +9,7 @@ use Cwd qw(cwd); repeat_each(2); -plan tests => repeat_each() * (blocks() * 5 - 1); +plan tests => repeat_each() * (blocks() * 5); my $pwd = cwd(); @@ -153,4 +153,111 @@ no match qr/\[TRACE \d+ "content_by_lua":5 loop\]/ --- no_error_log [error] +NYI + + + +=== TEST 4: nil submatch (2nd) +--- http_config eval: $::HttpConfig +--- config + location /re { + content_by_lua ' + local s = "hello, 1234" + local from, to, err + for i = 1, 100 do + from, to, err = ngx.re.find(s, "([0-9])|(hello world)", "jo", nil, 2) + end + if from or to then + ngx.say("from: ", from) + ngx.say("to: ", to) + ngx.say("matched: ", string.sub(s, from, to)) + else + if err then + ngx.say("error: ", err) + return + end + ngx.say("not matched!") + end + '; + } +--- request + GET /re +--- response_body +not matched! +--- no_error_log +[error] +NYI +--- error_log eval +qr/\[TRACE \d+ "content_by_lua":4 loop\]/ + + + +=== TEST 5: nil submatch (1st) +--- http_config eval: $::HttpConfig +--- config + location /re { + content_by_lua ' + local s = "hello, 1234" + local from, to, err + for i = 1, 100 do + from, to, err = ngx.re.find(s, "(hello world)|([0-9])", "jo", nil, 1) + end + if from or to then + ngx.say("from: ", from) + ngx.say("to: ", to) + ngx.say("matched: ", string.sub(s, from, to)) + else + if err then + ngx.say("error: ", err) + return + end + ngx.say("not matched!") + end + '; + } +--- request + GET /re +--- response_body +not matched! +--- no_error_log +[error] +NYI +--- error_log eval +qr/\[TRACE \d+ "content_by_lua":4 loop\]/ + + + +=== TEST 6: specify the group (2) +--- http_config eval: $::HttpConfig +--- config + location /re { + content_by_lua ' + local s = "hello, 1234" + local from, to, err + for i = 1, 100 do + from, to, err = ngx.re.find(s, "([0-9])([0-9]+)", "jo", nil, 2) + end + if from then + ngx.say("from: ", from) + ngx.say("to: ", to) + ngx.say("matched: ", string.sub(s, from, to)) + else + if err then + ngx.say("error: ", err) + end + ngx.say("not matched!") + end + '; + } +--- request + GET /re +--- response_body +from: 9 +to: 11 +matched: 234 +--- no_error_log +[error] +NYI +--- error_log eval +qr/\[TRACE \d+ "content_by_lua":4 loop\]/