Commit 77b36573 authored by Georg Brandl's avatar Georg Brandl

Add re.fullmatch() function and regex.fullmatch() method, which anchor the

pattern at both ends of the string to match.

Patch by Matthew Barnett.
Closes #16203.
parent a440d2b9
...@@ -584,6 +584,16 @@ form. ...@@ -584,6 +584,16 @@ form.
instead (see also :ref:`search-vs-match`). instead (see also :ref:`search-vs-match`).
.. function:: fullmatch(pattern, string, flags=0)
If the whole *string* matches the regular expression *pattern*, return a
corresponding :ref:`match object <match-objects>`. Return ``None`` if the
string does not match the pattern; note that this is different from a
zero-length match.
.. versionadded:: 3.4
.. function:: split(pattern, string, maxsplit=0, flags=0) .. function:: split(pattern, string, maxsplit=0, flags=0)
Split *string* by the occurrences of *pattern*. If capturing parentheses are Split *string* by the occurrences of *pattern*. If capturing parentheses are
...@@ -778,6 +788,24 @@ attributes: ...@@ -778,6 +788,24 @@ attributes:
:meth:`~regex.search` instead (see also :ref:`search-vs-match`). :meth:`~regex.search` instead (see also :ref:`search-vs-match`).
.. method:: regex.fullmatch(string[, pos[, endpos]])
If the whole *string* matches this regular expression, return a corresponding
:ref:`match object <match-objects>`. Return ``None`` if the string does not
match the pattern; note that this is different from a zero-length match.
The optional *pos* and *endpos* parameters have the same meaning as for the
:meth:`~regex.search` method.
>>> pattern = re.compile("o[gh]")
>>> pattern.fullmatch("dog") # No match as "o" is not at the start of "dog".
>>> pattern.fullmatch("ogre") # No match as not the full string matches.
>>> pattern.fullmatch("doggie", 1, 3) # Matches within given limits.
<_sre.SRE_Match object at ...>
.. versionadded:: 3.4
.. method:: regex.split(string, maxsplit=0) .. method:: regex.split(string, maxsplit=0)
Identical to the :func:`split` function, using the compiled pattern. Identical to the :func:`split` function, using the compiled pattern.
......
...@@ -86,6 +86,7 @@ resulting RE will match the second character. ...@@ -86,6 +86,7 @@ resulting RE will match the second character.
This module exports the following functions: This module exports the following functions:
match Match a regular expression pattern to the beginning of a string. match Match a regular expression pattern to the beginning of a string.
fullmatch Match a regular expression pattern to all of a string.
search Search a string for the presence of a pattern. search Search a string for the presence of a pattern.
sub Substitute occurrences of a pattern found in a string. sub Substitute occurrences of a pattern found in a string.
subn Same as sub, but also return the number of substitutions made. subn Same as sub, but also return the number of substitutions made.
...@@ -123,7 +124,7 @@ import sre_compile ...@@ -123,7 +124,7 @@ import sre_compile
import sre_parse import sre_parse
# public symbols # public symbols
__all__ = [ "match", "search", "sub", "subn", "split", "findall", __all__ = [ "match", "fullmatch", "search", "sub", "subn", "split", "findall",
"compile", "purge", "template", "escape", "A", "I", "L", "M", "S", "X", "compile", "purge", "template", "escape", "A", "I", "L", "M", "S", "X",
"U", "ASCII", "IGNORECASE", "LOCALE", "MULTILINE", "DOTALL", "VERBOSE", "U", "ASCII", "IGNORECASE", "LOCALE", "MULTILINE", "DOTALL", "VERBOSE",
"UNICODE", "error" ] "UNICODE", "error" ]
...@@ -154,6 +155,11 @@ def match(pattern, string, flags=0): ...@@ -154,6 +155,11 @@ def match(pattern, string, flags=0):
a match object, or None if no match was found.""" a match object, or None if no match was found."""
return _compile(pattern, flags).match(string) return _compile(pattern, flags).match(string)
def fullmatch(pattern, string, flags=0):
"""Try to apply the pattern to all of the string, returning
a match object, or None if no match was found."""
return _compile(pattern, flags).fullmatch(string)
def search(pattern, string, flags=0): def search(pattern, string, flags=0):
"""Scan through string looking for a match to the pattern, returning """Scan through string looking for a match to the pattern, returning
a match object, or None if no match was found.""" a match object, or None if no match was found."""
......
...@@ -1061,6 +1061,30 @@ class ReTests(unittest.TestCase): ...@@ -1061,6 +1061,30 @@ class ReTests(unittest.TestCase):
self.assertEqual(m.group(1), "") self.assertEqual(m.group(1), "")
self.assertEqual(m.group(2), "y") self.assertEqual(m.group(2), "y")
def test_fullmatch(self):
# Issue 16203: Proposal: add re.fullmatch() method.
self.assertEqual(re.fullmatch(r"a", "a").span(), (0, 1))
self.assertEqual(re.fullmatch(r"a|ab", "ab").span(), (0, 2))
self.assertEqual(re.fullmatch(r".*?$", "abc").span(), (0, 3))
self.assertEqual(re.fullmatch(r".*?", "abc").span(), (0, 3))
self.assertEqual(re.fullmatch(r"a.*?b", "ab").span(), (0, 2))
self.assertEqual(re.fullmatch(r"a.*?b", "abb").span(), (0, 3))
self.assertEqual(re.fullmatch(r"a.*?b", "axxb").span(), (0, 4))
self.assertEqual(re.fullmatch(r"abc$", "abc\n"), None)
self.assertEqual(re.fullmatch(r"abc\Z", "abc\n"), None)
self.assertEqual(re.fullmatch(r"(?m)abc$", "abc\n"), None)
self.assertEqual(re.fullmatch(r"ab(?=c)cd", "abcd").span(), (0, 4))
self.assertEqual(re.fullmatch(r"ab(?<=b)cd", "abcd").span(), (0, 4))
self.assertEqual(re.fullmatch(r"(?=a|ab)ab", "ab").span(), (0, 2))
self.assertEqual(
re.compile(r"bc").fullmatch("abcd", pos=1, endpos=3).span(), (1, 3))
self.assertEqual(
re.compile(r".*?$").fullmatch("abcd", pos=1, endpos=3).span(), (1, 3))
self.assertEqual(
re.compile(r".*?").fullmatch("abcd", pos=1, endpos=3).span(), (1, 3))
def run_re_tests(): def run_re_tests():
from test.re_tests import tests, SUCCEED, FAIL, SYNTAX_ERROR from test.re_tests import tests, SUCCEED, FAIL, SYNTAX_ERROR
if verbose: if verbose:
......
This diff is collapsed.
...@@ -89,6 +89,7 @@ typedef struct { ...@@ -89,6 +89,7 @@ typedef struct {
SRE_REPEAT *repeat; SRE_REPEAT *repeat;
/* hooks */ /* hooks */
SRE_TOLOWER_HOOK lower; SRE_TOLOWER_HOOK lower;
int match_all;
} SRE_STATE; } SRE_STATE;
typedef struct { typedef struct {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment