9
9
is_string_like ,
10
10
is_list_like ,
11
11
is_scalar ,
12
- is_integer )
12
+ is_integer ,
13
+ is_re )
13
14
from pandas .core .common import _values_from_object
14
15
15
16
from pandas .core .algorithms import take_1d
@@ -303,16 +304,20 @@ def str_endswith(arr, pat, na=np.nan):
303
304
return _na_map (f , arr , na , dtype = bool )
304
305
305
306
306
- def str_replace (arr , pat , repl , n = - 1 , case = True , flags = 0 ):
307
+ def str_replace (arr , pat , repl , n = - 1 , case = None , flags = None ):
307
308
"""
308
309
Replace occurrences of pattern/regex in the Series/Index with
309
310
some other string. Equivalent to :meth:`str.replace` or
310
311
:func:`re.sub`.
311
312
312
313
Parameters
313
314
----------
314
- pat : string
315
- Character sequence or regular expression
315
+ pat : string or compiled regex
316
+ String can be a character sequence or regular expression.
317
+
318
+ .. versionadded:: 0.20.0
319
+ `pat` also accepts a compiled regex.
320
+
316
321
repl : string or callable
317
322
Replacement string or a callable. The callable is passed the regex
318
323
match object and must return a replacement string to be used.
@@ -323,10 +328,11 @@ def str_replace(arr, pat, repl, n=-1, case=True, flags=0):
323
328
324
329
n : int, default -1 (all)
325
330
Number of replacements to make from start
326
- case : boolean, default True
327
- If True, case sensitive
328
- flags : int, default 0 (no flags)
329
- re module flags, e.g. re.IGNORECASE
331
+ case : boolean, default None (case sensitive)
332
+ If False, case insensitive. Must be None if `pat` is a compiled regex.
333
+ flags : int, default None (no flags)
334
+ re module flags, e.g. re.IGNORECASE. Must be None if `pat` is a
335
+ compiled regex.
330
336
331
337
Returns
332
338
-------
@@ -372,21 +378,48 @@ def str_replace(arr, pat, repl, n=-1, case=True, flags=0):
372
378
0 tWO
373
379
1 bAR
374
380
dtype: object
381
+
382
+ When `pat` is a compiled regex, all flags should be included in the
383
+ compiled regex. Use of `case` or `flags` with a compiled regex will
384
+ raise an error.
385
+
386
+ >>> regex_pat = re.compile(r'FUZ', flags=re.IGNORECASE)
387
+ >>> pd.Series(['foo', 'fuz', np.nan]).str.replace(regex_pat, 'bar')
388
+ 0 foo
389
+ 1 bar
390
+ 2 NaN
391
+ dtype: object
375
392
"""
376
393
377
394
# Check whether repl is valid (GH 13438, GH 15055)
378
395
if not (is_string_like (repl ) or callable (repl )):
379
396
raise TypeError ("repl must be a string or callable" )
380
- use_re = not case or len (pat ) > 1 or flags or callable (repl )
381
397
382
- if use_re :
383
- if not case :
398
+ is_compiled_re = is_re (pat )
399
+ if is_compiled_re :
400
+ if (case is not None ) or (flags is not None ):
401
+ raise ValueError ("case and flags must be None"
402
+ " when pat is a compiled regex" )
403
+ # Python2's re.sub requires that flag is an int
404
+ if compat .PY2 :
405
+ flags = 0
406
+ else :
407
+ # not a compiled regex
408
+ # set default case/flags
409
+ if case is None :
410
+ case = True
411
+ if flags is None :
412
+ flags = 0
413
+ # add case flag, if provided
414
+ if case is False :
384
415
flags |= re .IGNORECASE
385
- regex = re .compile (pat , flags = flags )
386
- n = n if n >= 0 else 0
387
416
388
- def f (x ):
389
- return regex .sub (repl , x , count = n )
417
+ use_re = is_compiled_re or len (pat ) > 1 or flags or callable (repl )
418
+
419
+ if use_re :
420
+ n = n if n >= 0 else 0
421
+ f = lambda x : re .sub (pattern = pat , repl = repl , string = x ,
422
+ count = n , flags = flags )
390
423
else :
391
424
f = lambda x : x .replace (pat , repl , n )
392
425
@@ -1558,7 +1591,7 @@ def match(self, pat, case=True, flags=0, na=np.nan, as_indexer=False):
1558
1591
return self ._wrap_result (result )
1559
1592
1560
1593
@copy (str_replace )
1561
- def replace (self , pat , repl , n = - 1 , case = True , flags = 0 ):
1594
+ def replace (self , pat , repl , n = - 1 , case = None , flags = None ):
1562
1595
result = str_replace (self ._data , pat , repl , n = n , case = case ,
1563
1596
flags = flags )
1564
1597
return self ._wrap_result (result )
0 commit comments