pandas-dev/pandas · error · NotImplementedError

replace is not supported with a re.Pattern, callable repl, c

Error message

replace is not supported with a re.Pattern, callable repl, case=False, flags!=0, or when the replacement string contains named group references (\g<...>)

What it means

Series.str.replace on the pyarrow backend cannot express every feature of Python's re module. It raises NotImplementedError when pat is a compiled re.Pattern, repl is callable, case=False, flags is non-zero, or the replacement string contains a named-group reference \g<...>. pyarrow's replace_substring(_regex) kernels have no equivalent for those, so pandas refuses rather than silently producing wrong results.

Source

Thrown at pandas/core/arrays/_arrow_string_mixins.py:262

        )

    def _str_replace(
        self,
        pat: str | re.Pattern,
        repl: str | Callable,
        n: int = -1,
        case: bool = True,
        flags: int = 0,
        regex: bool = True,
    ) -> Self:
        if (
            isinstance(pat, re.Pattern)
            or callable(repl)
            or not case
            or flags
            or (isinstance(repl, str) and r"\g<" in repl)
        ):
            raise NotImplementedError(
                "replace is not supported with a re.Pattern, callable repl, "
                "case=False, flags!=0, or when the replacement string contains "
                "named group references (\\g<...>)"
            )

        if pat == "":
            # pyarrow hangs for empty patterns
            # (https://github.com/apache/arrow/issues/39149)
            # use same func definition as ObjectStringArrayMixin._str_replace
            if regex:
                count = n if n >= 0 else 0
                func = lambda val: re.sub(pat, repl, val, count=count)
            else:
                func = lambda val: val.replace(pat, repl, n)

            result = self._apply_elementwise(func)
            return self._from_pyarrow_array(
                pa.chunked_array(result, type=self._pa_array.type)

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Convert to object dtype first: s.astype(object).str.replace(...) recovers full re semantics.
  2. Drop the unsupported feature: use a plain string pattern, a string repl, default case/flags, and numeric group refs like \1 instead of \g<name>.
  3. Move callable-replacement logic out of str.replace into an apply/elementwise step.

Example fix

// before
s.str.replace(r"\d+", lambda m: f"[{m.group()}]", regex=True)
// after
s.astype(object).str.replace(r"\d+", lambda m: f"[{m.group()}]", regex=True)
Defensive patterns

Strategy: fallback

Validate before calling

def pyarrow_replace(s, pat, repl, **kw):
    needs_object = (
        isinstance(pat, re.Pattern)
        or callable(repl)
        or not kw.get("case", True)
        or kw.get("flags", 0)
        or (isinstance(repl, str) and r"\g<" in repl)
    )
    if needs_object and "string[pyarrow]" in str(s.dtype):
        s = s.astype(object)
    return s.str.replace(pat, repl, **kw)

Try / catch

try:
    out = s.str.replace(pat, repl, regex=True)
except NotImplementedError:
    out = s.astype(object).str.replace(pat, repl, regex=True)

Prevention

When it happens

Trigger: On a string[pyarrow] Series: s.str.replace(r'\d+', lambda m: ..., regex=True); s.str.replace(pat, repl, flags=re.IGNORECASE); s.str.replace(compiled_re, 'x'); s.str.replace('a', r'\g<name>'); or s.str.replace('a','b', case=False).

Common situations: Migrating object/string-dtype code that relies on callable replacements or re flags to pyarrow dtypes; using named-group backreferences in replacement templates.

Related errors


AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07). Data as JSON: /api/errors/319db337ada2d300. Report an issue: GitHub.