diff --git a/src/Fable.Cli/CHANGELOG.md b/src/Fable.Cli/CHANGELOG.md index ca4aac4d29..8e4964af27 100644 --- a/src/Fable.Cli/CHANGELOG.md +++ b/src/Fable.Cli/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Fix #3615: Fix remove from dictionary with tuple as key * Fix #3598: Using obj () now generated an empty dict instead of None * Fix #3597: Do not translate .toString methods to str +* Fix #3610: Cleanup Python regex handling ## 4.6.0 - 2023-11-27 diff --git a/src/Fable.Transforms/Python/Replacements.fs b/src/Fable.Transforms/Python/Replacements.fs index 964465437e..225d43bbc0 100644 --- a/src/Fable.Transforms/Python/Replacements.fs +++ b/src/Fable.Transforms/Python/Replacements.fs @@ -5529,6 +5529,9 @@ let regex | Some(ExprType(DeclaredTypeFullName Types.regexGroup)) -> true | _ -> false + let createRegex r t args = + Helper.LibCall(com, "RegExp", "create", t, args, ?loc = r) + match i.CompiledName with // TODO: Use RegexConst if no options have been passed? | ".ctor" -> @@ -5611,6 +5614,36 @@ let regex | "get_Count" -> Helper.GlobalCall("len", t, [ thisArg.Value ], [ t ], ?loc = r) |> Some | "GetEnumerator" -> getEnumerator com r t thisArg.Value |> Some + | "IsMatch" + | "Match" + | "Matches" as meth -> + match thisArg, args with + | Some thisArg, args -> + if args.Length > 2 then + $"Regex.{meth} doesn't support more than 2 arguments" + |> addError com ctx.InlinePath r + + thisArg :: args |> Some + | None, input :: pattern :: args -> + let reg = createRegex None Any (pattern :: args) + + [ + reg + input + ] + |> Some + | _ -> None + |> Option.map (fun args -> + Helper.LibCall( + com, + "RegExp", + Naming.lowerFirst meth, + t, + args, + i.SignatureArgTypes, + ?loc = r + ) + ) | meth -> let meth = Naming.removeGetSetPrefix meth |> Naming.lowerFirst diff --git a/src/fable-library-py/fable_library/reg_exp.py b/src/fable-library-py/fable_library/reg_exp.py index 85a1ea8a7b..ba63c5941f 100644 --- a/src/fable-library-py/fable_library/reg_exp.py +++ b/src/fable-library-py/fable_library/reg_exp.py @@ -56,28 +56,15 @@ def unescape(string: str) -> str: return re.sub(r"\\(.)", r"\1", string) -def match(reg: Pattern[str] | str, input: str, start_at: int = 0) -> Match[str] | None: - if isinstance(reg, str): - flags = _options_to_flags(start_at) - return re.search(input, reg, flags) +def match(reg: Pattern[str], input: str, start_at: int = 0) -> Match[str] | None: return reg.search(input, pos=start_at) def matches(reg: Pattern[str], input: str, start_at: int = 0) -> list[Match[str]]: - if isinstance(reg, str): - flags = _options_to_flags(start_at) - input = input.replace("?<", "?P<") - return list(re.finditer(input, reg, flags=flags)) - return list(reg.finditer(input, pos=start_at)) -def is_match(reg: Pattern[str] | str, input: str, start_at: int = 0) -> bool: - if isinstance(reg, str): - # Note: input is the pattern here - flags = _options_to_flags(start_at) - return re.search(input, reg, flags=flags) is not None - +def is_match(reg: Pattern[str], input: str, start_at: int = 0) -> bool: return reg.search(input, pos=start_at) is not None