re: Add support for start- and endpos.

Pattern objects have two additional parameters for the ::search and
::match methods to define the starting and ending position of the
subject within the string to be searched.

This allows for searching a sub-string without creating a slice.
However, one caveat of using the start-pos rather than a slice is that
the start anchor (`^`) remains anchored to the beginning of the text.
pull/14179/head
Jared Hancock 2024-03-25 20:58:51 -05:00
rodzic 9d27183bde
commit 6f3c6d7de9
3 zmienionych plików z 96 dodań i 1 usunięć

Wyświetl plik

@ -195,10 +195,11 @@ static void re_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t
}
static mp_obj_t re_exec(bool is_anchored, uint n_args, const mp_obj_t *args) {
(void)n_args;
mp_obj_re_t *self;
bool was_compiled = false;
if (mp_obj_is_type(args[0], (mp_obj_type_t *)&re_type)) {
self = MP_OBJ_TO_PTR(args[0]);
was_compiled = true;
} else {
self = MP_OBJ_TO_PTR(mod_re_compile(1, args));
}
@ -206,6 +207,27 @@ static mp_obj_t re_exec(bool is_anchored, uint n_args, const mp_obj_t *args) {
size_t len;
subj.begin_line = subj.begin = mp_obj_str_get_data(args[1], &len);
subj.end = subj.begin + len;
if (was_compiled && n_args > 2) {
// Arg #2 is starting-pos
size_t startpos = mp_obj_get_int(args[2]);
if (startpos >= len) {
startpos = len;
}
subj.begin += startpos;
if (n_args > 3) {
// Arg #3 is ending-pos
size_t endpos = mp_obj_get_int(args[3]);
if (endpos > len) {
endpos = len;
}
else if (endpos < startpos) {
endpos = startpos;
}
subj.end = subj.begin_line + endpos;
}
}
int caps_num = (self->re.sub + 1) * 2;
mp_obj_match_t *match = m_new_obj_var(mp_obj_match_t, caps, char *, caps_num);
// cast is a workaround for a bug in msvc: it treats const char** as a const pointer instead of a pointer to pointer to const char

Wyświetl plik

@ -0,0 +1,59 @@
# test start and end pos specification
try:
import re
except ImportError:
print("SKIP")
raise SystemExit
def print_groups(match):
print("----")
try:
if match is not None:
i = 0
while True:
print(match.group(i))
i += 1
except IndexError:
pass
p = re.compile(r"o")
m = p.match("dog")
print_groups(m)
m = p.match("dog", 1)
print_groups(m)
m = p.match("dog", 2)
print_groups(m)
m = p.match("dog", 3) # Past end of input
print_groups(m)
m = p.match("dog", 0, 1)
print_groups(m)
# Caret only matches the actual beginning
p = re.compile(r"^o")
m = p.match("dog", 1)
print_groups(m)
# End at begging means searching empty string
p = re.compile(r"o")
m = p.match("dog", 1, 1)
print_groups(m)
# Search also works
print('--search')
p = re.compile(r"o")
m = p.search('dog')
print_groups(m)
m = p.search('dog', 1)
print_groups(m)
m = p.search('dog', 2)
print_groups(m)

Wyświetl plik

@ -0,0 +1,14 @@
----
----
o
----
----
----
----
----
--search
----
o
----
o
----