BUG: Replace on Series/DataFrame stops replacing after first NA
State: closed

- [x] closes #56599
- [x] [Tests added and passed](https://pandas.pydata.org/pandas-docs/dev/development/contributing_codebase.html#writing-tests) if fixing a bug or adding a new feature
- [x] All [code checks passed](https://pandas.pydata.org/pandas-docs/dev/development/contributing_codebase.html#pre-commit).
- [x] Added [type annotations](https://pandas.pydata.org/pandas-docs/dev/development/contributing_codebase.html#type-hints) to new arguments/methods/functions.
- [x] Added an entry in the latest `doc/source/whatsnew/vX.X.X.rst` file if fixing a bug or adding a new feature.

The issue was the line `a = a[mask]` was triggered only for `ndarray` and doesn't hit when `dtype='string'`, but the `np.place` logic applied as long as the result was an `ndarray`.

The old behavior had things like (depending on the number and location of NAs)

```py
In [2]: s = pd.Series(['m', 'm', pd.NA, 'm', 'm', 'm'], dtype='string')

In [3]: s.replace({'m': 't'}, regex=True)
Out[3]:
0       t
1       t
2    <NA>
3       m
4       t
5       t
dtype: string

In [4]: s = pd.Series(['m', 'm', pd.NA, pd.NA, 'm', 'm', 'm'], dtype='string')

In [5]: s.replace({'m': 't'}, regex=True)
Out[5]:
0       t
1       t
2    <NA>
3    <NA>
4       m
5       m
6       t
dtype: string

In [6]: s = pd.Series(['m', 'm', pd.NA, 'm', 'm', pd.NA, 'm', 'm'], dtype='string')

In [7]: s.replace({'m': 't'}, regex=True)
Out[7]:
0       t
1       t
2    <NA>
3       m
4       t
5    <NA>
6       t
7       m
dtype: string
```

Labels:
name: Missing-data
description: np.nan, pd.NaT, pd.NA, dropna, isnull, interpolate
name: replace
description: replace method
name: Still Needs Manual Backport

Comments:
pre-commit.ci autofix
Thanks @asishm 
Along with other string type fixes, I think it'd be good to backport this to 2.3.x. Any objection @mroeschke @jorisvandenbossche?
No objection from me
@MeeseeksDev backport to 2.3.x
Owee, I'm MrMeeseeks, Look at me.

There seem to be a conflict, please backport manually. Here are approximate instructions:

1. Checkout backport branch and update it.

```
git checkout 2.3.x
git pull
```

2. Cherry pick the first parent branch of the this PR on top of the older branch:
```
git cherry-pick -x -m1 0f7ded2a3a637b312f6ad454fd6c0b89d3d3e7aa
```

3. You will likely have some merge/cherry-pick conflict here, fix them and commit:

```
git commit -am 'Backport PR #57865: BUG: Replace on Series/DataFrame stops replacing after first NA'
```

4. Push to a named branch:

```
git push YOURFORK 2.3.x:auto-backport-of-pr-57865-on-2.3.x
```

5. Create a PR against branch 2.3.x, I would have named this PR:

> "Backport PR #57865 on branch 2.3.x (BUG: Replace on Series/DataFrame stops replacing after first NA)"

And apply the correct labels and milestones.

Congratulations — you did some good work! Hopefully your backport PR will be tested by the continuous integration and merged soon!

Remember to remove the `Still Needs Manual Backport` label once the PR gets merged.

If these instructions are inaccurate, feel free to [suggest an improvement](https://github.com/MeeseeksBox/MeeseeksDev).