diff --git a/re2/re2.cc b/re2/re2.cc index ca9775e1f27a91567b699f4c46991f8e096923e0..91d9880f4d02aa56d848b80ca69d7c2769c439d0 100644 --- a/re2/re2.cc +++ b/re2/re2.cc @@ -1023,22 +1023,7 @@ namespace re2 // E.g. if rewrite == "foo \\2,\\1", returns 2. int RE2::MaxSubmatch(const StringPiece &rewrite) { - int max = 0; - for (const char *s = rewrite.data(), *end = s + rewrite.size(); - s < end; s++) - { - if (*s == '\\') - { - s++; - int c = (s < end) ? *s : -1; - if (isdigit(c)) - { - int n = (c - '0'); - if (n > max) - max = n; - } - } - } + int max = rure_max_submatch(rewrite.data()); return max; } diff --git a/regex-capi/include/rure.h b/regex-capi/include/rure.h index 1817e25869e22d7907f5b62663f2618f2058ec11..67194866ae31bab1343f5179f1b316710b166d07 100644 --- a/regex-capi/include/rure.h +++ b/regex-capi/include/rure.h @@ -610,6 +610,7 @@ const char *rure_replace_all(rure *re, const uint8_t *haystack, size_t len_h, rure *rure_new(const uint8_t *pattern, size_t length); bool rure_consume(rure *re, const uint8_t *haystack, size_t length, rure_match *match); +int rure_max_submatch(const char *rewrite); #ifdef __cplusplus } diff --git a/regex-capi/src/rure.rs b/regex-capi/src/rure.rs index 17e35524d4a2a7a5cc86297cdea9472a47bbc4fe..b88ffc4bfb5886823dd9af9b6b672c8373fb2ed0 100644 --- a/regex-capi/src/rure.rs +++ b/regex-capi/src/rure.rs @@ -721,3 +721,29 @@ ffi_fn! { } } + +ffi_fn! { + fn rure_max_submatch(rewrite: *const c_char) -> i32 { + let mut max: i32 = 0; + let mut flag = 0; + let zero_number = '0' as i32; + let len = unsafe { CStr::from_ptr(rewrite).to_bytes().len() }; + let pat = rewrite as *const u8; + let text = unsafe { slice::from_raw_parts(pat, len) }; + let rewrite = std::str::from_utf8(text).unwrap(); + for s in rewrite.chars() { + if s == '\\' { + flag = 1; + continue; + } + if s.is_ascii_digit() && flag == 1 { + let max_ = s as i32 - zero_number; + if max_ > max { + max = max_; + } + flag = 0; + } + } + max + } +}