From 9641598a37604592aef01b0337f405a5c2c063d7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 24 Apr 2026 01:22:11 +0000 Subject: [PATCH 1/2] fix(python): fix regex lookbehind patterns being incorrectly converted The create() function in reg_exp.py used a plain string replace to convert .NET named group syntax (?...) to Python (?P...). This also incorrectly converted positive lookbehind (?<=...) to (?P<=...) Fix: use a regex substitution that only replaces ?< when followed by a word character (the start of a valid group name), leaving lookbehind assertion syntax intact. Closes #3918 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/fable-library-py/fable_library/reg_exp.py | 5 ++++- tests/Python/TestRegex.fs | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/fable-library-py/fable_library/reg_exp.py b/src/fable-library-py/fable_library/reg_exp.py index 5dc5f1f5c9..aef8cc9f99 100644 --- a/src/fable-library-py/fable_library/reg_exp.py +++ b/src/fable-library-py/fable_library/reg_exp.py @@ -71,7 +71,10 @@ def _options_to_flags(options: int) -> int: def create(pattern: str, options: int = 0) -> Pattern[str]: # raw_pattern = pattern.encode("unicode_escape").decode("utf-8") flags = _options_to_flags(options) - pattern = pattern.replace("?<", "?P<") + # Convert .NET named group syntax (?...) to Python (?P...). + # Only replace ?< when followed by a word character (name start), not by + # = or ! which are part of lookbehind assertions (?<=...) and (? equal expected + +[] +let ``test positive lookbehind works`` () = + let r = Regex @"(?<=A)\w+" + let text = "AB AC AD BD" + let ms = r.Matches(text) |> Seq.map (fun m -> m.Value) |> Seq.toList + ms |> equal [ "B"; "C"; "D" ] + +[] +let ``test negative lookbehind works`` () = + let r = Regex @"(? Seq.map (fun m -> m.Value) |> Seq.toList + ms |> equal [ "BD" ] From 4b7ab0abdf4a71b3938d4e2756bb41f196785c4c Mon Sep 17 00:00:00 2001 From: Dag Brattli Date: Sat, 25 Apr 2026 10:05:03 +0200 Subject: [PATCH 2/2] fix(test): correct negative lookbehind test expectation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous test used `(? --- tests/Python/TestRegex.fs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Python/TestRegex.fs b/tests/Python/TestRegex.fs index ec8074274e..de19016043 100644 --- a/tests/Python/TestRegex.fs +++ b/tests/Python/TestRegex.fs @@ -646,7 +646,7 @@ let ``test positive lookbehind works`` () = [] let ``test negative lookbehind works`` () = - let r = Regex @"(? Seq.map (fun m -> m.Value) |> Seq.toList - ms |> equal [ "BD" ] + ms |> equal [ "2"; "4" ]