Examples
When pat is a string and regex is True (the default), the given pat is compiled as a regex.
When repl is a string, it replaces matching regex patterns as with re.sub(). NaN value(s)
in the Series are left as is:

In [1]:
import numpy as np
import pandas as pd
In [2]:
pd.Series(['full', 'fog', np.nan]).str.replace('f.', 'bu', regex=True)
Out[2]:
0    bull
1     bug
2     NaN
dtype: object

When pat is a string and regex is False, every pat is replaced with repl
as with str.replace():

In [3]:
pd.Series(['f.n', 'fog', np.nan]).str.replace('f.', 'bu', regex=False)
Out[3]:
0    bun
1    fog
2    NaN
dtype: object

When repl is a callable, it is called on every pat using re.sub(). The callable should expect
one positional argument (a regex object) and return a string.

To get the idea:

In [4]:
pd.Series(['full', 'fog', np.nan]).str.replace('f', repr)
Out[4]:
0    <re.Match object; span=(0, 1), match='f'>ull
1     <re.Match object; span=(0, 1), match='f'>og
2                                             NaN
dtype: object

Reverse every lowercase alphabetic word:

In [5]:
repl = lambda m: m.group(0)[::-1]
pd.Series(['full 234', 'brr bzz', np.nan]).str.replace(r'[a-z]+', repl)
Out[5]:
0    lluf 234
1     rrb zzb
2         NaN
dtype: object

Using regex groups (extract second group and swap case):

In [6]:
pat = r"(?P<one>\w+) (?P<two>\w+) (?P<three>\w+)"
repl = lambda m: m.group('two').swapcase()
pd.Series(['One Two Three', 'Full Brr Bzz']).str.replace(pat, repl)
Out[6]:
0    tWO
1    bRR
dtype: object

Using a compiled regex with flags

In [7]:
import re
regex_pat = re.compile(r'FOG', flags=re.IGNORECASE)
pd.Series(['full', 'fog', np.nan]).str.replace(regex_pat, 'brr')
Out[7]:
0    full
1     brr
2     NaN
dtype: object