Repository: pandas-dev/pandas (python)

Issue:
BUG: Printing of a pandas Series of complex numbers with e-notation has broken between 2.0.x and older versions and the newer 2.1.x, 2.2.x versions
### Pandas version checks

- [X] I have checked that this issue has not already been reported.

- [X] I have confirmed this bug exists on the [latest version](https://pandas.pydata.org/docs/whatsnew/index.html) of pandas.

- [ ] I have confirmed this bug exists on the [main branch](https://pandas.pydata.org/docs/dev/getting_started/install.html#installing-the-development-version-of-pandas) of pandas.


### Reproducible Example

```python
import pandas as pd
input_array = [(1.8816e-09+0j), (3.39676e-09+0j)]
print("input_array=\n", input_array)
print("pd.Series(input_array)=\n", pd.Series(input_array))
```


### Issue Description

We use the pandas Series method to store a list of complex numbers but when upgrading from the pandas 1.3, 1.5, or 2.0 versions we are seeing a regression issue where in pandas 2.1.x and 2.2.x and latest 2.2.3 version the print out is adding extra white space to the imaginary value's e-notation portion.

example:
`import pandas as pd`
`input_array = [(1.8816e-09+0j), (3.39676e-09+0j)]`
`print("input_array=\n", input_array)`
`print("pd.Series(input_array)=\n", pd.Series(input_array))`


For example in pandas 1.3, 1.5, 2.0.3 we see the following output that we expect from the following example:

`input_array=`
` [(1.8816e-09+0j), (3.39676e-09+0j)]`
`pd.Series(input_array)=`
` 0    1.881600e-09+0.000000e+00j`
`1    3.396760e-09+0.000000e+00j`
`dtype: complex128`

But now in pandas version 2.1.x, 2.2.x, and latest 2.2.3 we are getting the output instead:
`input_array=`
` [(1.8816e-09+0j), (3.39676e-09+0j)]`
`pd.Series(input_array)=`
` 0    1.881600e-09+0.000000e+                    00j`
`1    3.396760e-09+0.000000e+                    00j`
`dtype: complex128`

Thanks.

### Expected Behavior

The expected output is the following:
`input_array=`
` [(1.8816e-09+0j), (3.39676e-09+0j)]`
`pd.Series(input_array)=`
` 0    1.881600e-09+0.000000e+00j`
`1    3.396760e-09+0.000000e+00j`
`dtype: complex128`

Where the `+0j` portion of the complex value is printed as `+0.000000e+00j` 
not what it is printed now as: `0.000000e+                    00j`

### Installed Versions

<details>

INSTALLED VERSIONS
------------------
commit                : 0691c5cf90477d3503834d983f69350f250a6ff7
python                : 3.12.2
python-bits           : 64
OS                    : Windows
OS-release            : 10
Version               : 10.0.19045
machine               : AMD64
processor             : Intel64 Family 6 Model 141 Stepping 1, GenuineIntel
byteorder             : little
LC_ALL                : None
LANG                  : None
LOCALE                : English_United States.1252

pandas                : 2.2.3
numpy                 : 1.26.4
pytz                  : 2024.2
dateutil              : 2.9.0.post0
pip                   : 24.2
Cython                : None
sphinx                : None
IPython               : None
adbc-driver-postgresql: None
adbc-driver-sqlite    : None
bs4                   : None
blosc                 : None
bottleneck            : None
dataframe-api-compat  : None
fastparquet           : None
fsspec                : None
html5lib              : None
hypothesis            : None
gcsfs                 : None
jinja2                : 3.1.4
lxml.etree            : None
matplotlib            : None
numba                 : None
numexpr               : None
odfpy                 : None
openpyxl              : None
pandas_gbq            : None
psycopg2              : None
pymysql               : None
pyarrow               : None
pyreadstat            : None
pytest                : 8.3.3
python-calamine       : None
pyxlsb                : None
s3fs                  : None
scipy                 : None
sqlalchemy            : None
tables                : None
tabulate              : None
xarray                : None
xlrd                  : None
xlsxwriter            : None
zstandard             : None
tzdata                : 2024.2
qtpy                  : None
pyqt5                 : None

</details>
Thanks

Pull request description:
BUG: Fix formatting of complex numbers with exponents
- [ ] closes #60393 
- [ ] [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
- [ ] All [code checks passed](https://pandas.pydata.org/pandas-docs/dev/development/contributing_codebase.html#pre-commit).
- [x] Added an entry in the latest `doc/source/whatsnew/v3.0.0.rst` file if fixing a bug or adding a new feature.

```
>>> input_array=[(1.8816e-09+0j), (3.39676e-09+0j)]
>>> pd.Series(input_array)
0    1.881600e-09+0.000000e+                    00j
1    3.396760e-09+0.000000e+                    00j
dtype: complex128
```

The issue was due to the regex in the _trim_zeros_complex function not being able to handle +/- in the exponent. It assumes the complex number string to be of the form (-)xxx(+/)yyyj. I fixed the regex so it doesn't split on +/- if preceded by an exponent.
Post the fix:

```
>>> input_array=[(1.8816e-09+0j), (3.39676e-09+0j)]
>>> pd.Series(input_array)
0    1.881600e-09+0.000000e+00j
1    3.396760e-09+0.000000e+00j
dtype: complex128
```

Patch:
diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst
index 1d55fc3ed7..1b12735f0e 100644
--- a/doc/source/whatsnew/v3.0.0.rst
+++ b/doc/source/whatsnew/v3.0.0.rst
@@ -789,6 +789,7 @@ Other
 - Bug in :meth:`Series.dt` methods in :class:`ArrowDtype` that were returning incorrect values. (:issue:`57355`)
 - Bug in :meth:`Series.rank` that doesn't preserve missing values for nullable integers when ``na_option='keep'``. (:issue:`56976`)
 - Bug in :meth:`Series.replace` and :meth:`DataFrame.replace` inconsistently replacing matching instances when ``regex=True`` and missing values are present. (:issue:`56599`)
+- Bug in :meth:`Series.to_string` when series contains complex floats with exponents (:issue:`60405`)
 - Bug in :meth:`read_csv` where chained fsspec TAR file and ``compression="infer"`` fails with ``tarfile.ReadError`` (:issue:`60028`)
 - Bug in Dataframe Interchange Protocol implementation was returning incorrect results for data buffers' associated dtype, for string and datetime columns (:issue:`54781`)
 - Bug in ``Series.list`` methods not preserving the original :class:`Index`. (:issue:`58425`)
diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py
index 861f5885f8..4f87b1a30c 100644
--- a/pandas/io/formats/format.py
+++ b/pandas/io/formats/format.py
@@ -1749,7 +1749,7 @@ def _trim_zeros_complex(str_complexes: ArrayLike, decimal: str = ".") -> list[st
         # The split will give [{"", "-"}, "xxx", "+/-", "xxx", "j", ""]
         # Therefore, the imaginary part is the 4th and 3rd last elements,
         # and the real part is everything before the imaginary part
-        trimmed = re.split(r"([j+-])", x)
+        trimmed = re.split(r"(?<!e)([j+-])", x)
         real_part.append("".join(trimmed[:-4]))
         imag_part.append("".join(trimmed[-4:-2]))
 


Test patch:
diff --git a/pandas/tests/io/formats/test_to_string.py b/pandas/tests/io/formats/test_to_string.py
index 5731f74a03..af3cdf2d44 100644
--- a/pandas/tests/io/formats/test_to_string.py
+++ b/pandas/tests/io/formats/test_to_string.py
@@ -422,6 +422,24 @@ class TestToStringNumericFormatting:
             )
             assert result == expected
 
+    def test_to_string_complex_float_formatting_with_exponents(self):
+        # GH #60393
+        with option_context("display.precision", 6):
+            df = DataFrame(
+                {
+                    "x": [
+                        (1.8816e-09 + 0j),
+                        (1.8816e-09 + 3.39676e-09j),
+                    ]
+                }
+            )
+            result = df.to_string()
+            expected = (
+                "                            x\n0  1.881600e-09+0.000000e+00j\n"
+                "1  1.881600e-09+3.396760e-09j"
+            )
+            assert result == expected
+
     def test_to_string_format_inf(self):
         # GH#24861
         df = DataFrame(