Add a `re()` method to the `Filter` class.
Callers shouldn't have to duplicate the regular expressions.
Note that the name of the method is consistent with the name
of the property in the `_Match` class.
Change-Id: If418f820fd6d460cfa4d90f8a837f1cb7994608d
Reviewed-on: https://code-review.googlesource.com/c/re2/+/61170
Reviewed-by: Perry Lorier <perryl@google.com>
Reviewed-by: Paul Wankadia <junyer@google.com>
diff --git a/python/_re2.cc b/python/_re2.cc
index 10031ea..8564f8a 100644
--- a/python/_re2.cc
+++ b/python/_re2.cc
@@ -233,6 +233,10 @@
return matches;
}
+ const RE2& GetRE2(int index) const {
+ return filter_.GetRE2(index);
+ }
+
private:
re2::FilteredRE2 filter_;
std::unique_ptr<RE2::Set> set_;
@@ -326,7 +330,9 @@
filter.def(py::init<>())
.def("Add", &Filter::Add)
.def("Compile", &Filter::Compile)
- .def("Match", &Filter::Match);
+ .def("Match", &Filter::Match)
+ .def("GetRE2", &Filter::GetRE2,
+ py::return_value_policy::reference_internal);
}
} // namespace re2_python
diff --git a/python/re2.py b/python/re2.py
index 8af260f..8a6d985 100644
--- a/python/re2.py
+++ b/python/re2.py
@@ -413,7 +413,7 @@
group = self._regexp.groupindex[group]
except KeyError:
raise IndexError('bad group name')
- if group < 0 or group > self._regexp.groups:
+ if not 0 <= group <= self._regexp.groups:
raise IndexError('bad group index')
span = self._spans[group]
if span == _NULL_SPAN:
@@ -441,17 +441,17 @@
return dict(items)
def start(self, group=0):
- if group < 0 or group > self._regexp.groups:
+ if not 0 <= group <= self._regexp.groups:
raise IndexError('bad group index')
return self._spans[group][0]
def end(self, group=0):
- if group < 0 or group > self._regexp.groups:
+ if not 0 <= group <= self._regexp.groups:
raise IndexError('bad group index')
return self._spans[group][1]
def span(self, group=0):
- if group < 0 or group > self._regexp.groups:
+ if not 0 <= group <= self._regexp.groups:
raise IndexError('bad group index')
return self._spans[group]
@@ -543,10 +543,11 @@
class Filter(object):
"""A Pythonic wrapper around FilteredRE2."""
- __slots__ = ('_filter')
+ __slots__ = ('_filter', '_patterns')
def __init__(self):
self._filter = _re2.Filter()
+ self._patterns = []
def Add(self, pattern, options=None):
options = options or Options()
@@ -557,6 +558,7 @@
index = self._filter.Add(pattern, options)
if index == -1:
raise error('failed to add %r to Filter' % pattern)
+ self._patterns.append(pattern)
return index
def Compile(self):
@@ -570,3 +572,11 @@
else:
matches = self._filter.Match(text, potential)
return matches or None
+
+ def re(self, index):
+ if not 0 <= index < len(self._patterns):
+ raise IndexError('bad index')
+ proxy = object.__new__(_Regexp)
+ proxy._pattern = self._patterns[index]
+ proxy._regexp = self._filter.GetRE2(index)
+ return proxy
diff --git a/python/re2_test.py b/python/re2_test.py
index 9161c60..86aa9ae 100644
--- a/python/re2_test.py
+++ b/python/re2_test.py
@@ -471,6 +471,12 @@
self.assertItemsEqual([0, 1], f.Match('Hello, world.'))
self.assertIsNone(f.Match('HELLO, WORLD.'))
+ self.assertRaises(IndexError, f.re, -1)
+ self.assertRaises(IndexError, f.re, 3)
+ self.assertEqual('Goodbye, \\w+\\.', f.re(2).pattern)
+ # Verify whether the underlying RE2 object is usable.
+ self.assertEqual(0, f.re(2).groups)
+
if __name__ == '__main__':
absltest.main()