irex / engine.py
ntedvs's picture
Upload folder using huggingface_hub
521b329 verified
Raw History Blame Contribute Delete
1.03 kB
"""JavaScript regex semantics via embedded QuickJS."""
import json
import quickjs
_JS = r"""
function compiles(p, f) { try { new RegExp(p, f); return true } catch (e) { return false } }
function tests(p, f, xs) { const r = new RegExp(p, f); return JSON.stringify(JSON.parse(xs).map(s => r.test(s))) }
"""
_ctx = quickjs.Context()
_ctx.set_time_limit(0.05) # seconds; guards against catastrophic backtracking
_ctx.eval(_JS)
_compiles, _tests = _ctx.get("compiles"), _ctx.get("tests")
def compiles(pattern: str, flags: str = "") -> bool:
return bool(_compiles(pattern, flags))
def test(pattern: str, flags: str, strings: list[str]) -> list[bool]:
return json.loads(_tests(pattern, flags, json.dumps(strings)))
def literal(pattern: str, flags: str = "") -> str:
return f"/{pattern}/{flags}"
def parse_literal(s: str) -> tuple[str, str]:
s = s.strip()
if not s.startswith("/") or s.rfind("/") == 0:
raise ValueError(f"not a regex literal: {s!r}")
i = s.rfind("/")
return s[1:i], s[i + 1:]