Skip to content

Commit 5f66afe

Browse files
bpo-42885: Optimize search for regular expressions starting with "\A" or "^"
Affected functions are re.search(), re.split(), re.findall(), re.finditer() and re.sub().
1 parent 3ae975f commit 5f66afe

3 files changed

Lines changed: 19 additions & 0 deletions

File tree

Lib/test/test_re.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2072,6 +2072,15 @@ def test_bug_40736(self):
20722072
with self.assertRaisesRegex(TypeError, "got 'type'"):
20732073
re.search("x*", type)
20742074

2075+
def test_search_anchor_at_beginning(self):
2076+
s = 'x'*10**7
2077+
for p in r'\Ax*y', r'^x*y':
2078+
self.assertIsNone(re.search(p, s))
2079+
self.assertEqual(re.split(p, s), [s])
2080+
self.assertEqual(re.findall(p, s), [])
2081+
self.assertEqual(list(re.finditer(p, s)), [])
2082+
self.assertEqual(re.sub(p, '', s), s)
2083+
20752084

20762085
class PatternReprTests(unittest.TestCase):
20772086
def check(self, pattern, expected):
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Optimize :func:`re.search`, :func:`re.split`, :func:`re.findall`,
2+
:func:`re.finditer` and :func:`re.sub` for regular expressions starting with
3+
``\A`` or ``^``.

Modules/sre_lib.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1495,6 +1495,13 @@ SRE(search)(SRE_STATE* state, SRE_CODE* pattern)
14951495
state->start = state->ptr = ptr;
14961496
status = SRE(match)(state, pattern, 1);
14971497
state->must_advance = 0;
1498+
if (status == 0 && pattern[0] == SRE_OP_AT &&
1499+
(pattern[1] == SRE_AT_BEGINNING ||
1500+
pattern[1] == SRE_AT_BEGINNING_STRING))
1501+
{
1502+
state->start = state->ptr = ptr = end;
1503+
return 0;
1504+
}
14981505
while (status == 0 && ptr < end) {
14991506
ptr++;
15001507
RESET_CAPTURE_GROUP();

0 commit comments

Comments
 (0)