|
39 | 39 | import logging
|
40 | 40 | import operator
|
41 | 41 | import re
|
| 42 | +import re2 |
42 | 43 | import sys
|
43 | 44 | from functools import reduce, wraps
|
44 | 45 | from typing import (Any, Callable, Dict, Iterable, Iterator, List, Mapping,
|
|
62 | 63 |
|
63 | 64 | logger = logging.getLogger("evaluation")
|
64 | 65 |
|
65 |
| - |
66 | 66 | class CELSyntaxError(Exception):
|
67 | 67 | """CEL Syntax error -- the AST did not have the expected structure."""
|
68 | 68 | def __init__(self, arg: Any, line: Optional[int] = None, column: Optional[int] = None) -> None:
|
@@ -293,6 +293,15 @@ def operator_in(item: Result, container: Result) -> Result:
|
293 | 293 | return result
|
294 | 294 |
|
295 | 295 |
|
| 296 | +def function_matches(text: str, pattern: str): |
| 297 | + try: |
| 298 | + m = re2.search(pattern, text) |
| 299 | + except re2.error as ex: |
| 300 | + return CELEvalError("match error", ex.__class__, ex.args) |
| 301 | + |
| 302 | + return celpy.celtypes.BoolType(m is not None) |
| 303 | + |
| 304 | + |
296 | 305 | def function_size(container: Result) -> Result:
|
297 | 306 | """
|
298 | 307 | The size() function applied to a Value. Delegate to Python's :py:func:`len`.
|
@@ -340,7 +349,7 @@ def function_size(container: Result) -> Result:
|
340 | 349 | # StringType methods
|
341 | 350 | "endsWith": lambda s, text: celpy.celtypes.BoolType(s.endswith(text)),
|
342 | 351 | "startsWith": lambda s, text: celpy.celtypes.BoolType(s.startswith(text)),
|
343 |
| - "matches": lambda s, pattern: celpy.celtypes.BoolType(re.search(pattern, s) is not None), |
| 352 | + "matches": function_matches, |
344 | 353 | "contains": lambda s, text: celpy.celtypes.BoolType(text in s),
|
345 | 354 | # TimestampType methods. Type details are redundant, but required because of the lambdas
|
346 | 355 | "getDate": lambda ts, tz_name=None: celpy.celtypes.IntType(ts.getDate(tz_name)),
|
|
0 commit comments