@@ -904,27 +904,39 @@ def test_casemethods(self):
904
904
def test_replace (self ):
905
905
values = Series (['fooBAD__barBAD' , NA ])
906
906
907
- result = values .str .replace ('BAD[_]*' , '' )
907
+ result = values .str .replace ('BAD[_]*' , '' , regex = True )
908
908
exp = Series (['foobar' , NA ])
909
909
tm .assert_series_equal (result , exp )
910
910
911
- result = values .str .replace ('BAD[_]*' , '' , n = 1 )
911
+ result = values .str .replace ('BAD[_]*' , '' , regex = True , n = 1 )
912
912
exp = Series (['foobarBAD' , NA ])
913
913
tm .assert_series_equal (result , exp )
914
914
915
915
# mixed
916
916
mixed = Series (['aBAD' , NA , 'bBAD' , True , datetime .today (), 'fooBAD' ,
917
917
None , 1 , 2. ])
918
918
919
- rs = Series (mixed ).str .replace ('BAD[_]*' , '' )
919
+ rs = Series (mixed ).str .replace ('BAD[_]*' , '' , regex = True )
920
920
xp = Series (['a' , NA , 'b' , NA , NA , 'foo' , NA , NA , NA ])
921
921
assert isinstance (rs , Series )
922
922
tm .assert_almost_equal (rs , xp )
923
923
924
+ # unicode
925
+ values = Series ([u'fooBAD__barBAD' , NA ])
926
+
927
+ result = values .str .replace ('BAD[_]*' , '' , regex = True )
928
+ exp = Series ([u'foobar' , NA ])
929
+ tm .assert_series_equal (result , exp )
930
+
931
+ result = values .str .replace ('BAD[_]*' , '' , n = 1 , regex = True )
932
+ exp = Series ([u'foobarBAD' , NA ])
933
+ tm .assert_series_equal (result , exp )
934
+
924
935
# flags + unicode
925
936
values = Series ([b"abcd,\xc3 \xa0 " .decode ("utf-8" )])
926
937
exp = Series ([b"abcd, \xc3 \xa0 " .decode ("utf-8" )])
927
- result = values .str .replace (r"(?<=\w),(?=\w)" , ", " , flags = re .UNICODE )
938
+ result = values .str .replace (r"(?<=\w),(?=\w)" , ", " , regex = True ,
939
+ flags = re .UNICODE )
928
940
tm .assert_series_equal (result , exp )
929
941
930
942
# GH 13438
@@ -942,7 +954,7 @@ def test_replace_callable(self):
942
954
943
955
# test with callable
944
956
repl = lambda m : m .group (0 ).swapcase ()
945
- result = values .str .replace ('[a-z][A-Z]{2}' , repl , n = 2 )
957
+ result = values .str .replace ('[a-z][A-Z]{2}' , repl , n = 2 , regex = True )
946
958
exp = Series (['foObaD__baRbaD' , NA ])
947
959
tm .assert_series_equal (result , exp )
948
960
@@ -952,21 +964,21 @@ def test_replace_callable(self):
952
964
953
965
repl = lambda : None
954
966
with pytest .raises (TypeError , match = p_err ):
955
- values .str .replace ('a' , repl )
967
+ values .str .replace ('a' , repl , regex = True )
956
968
957
969
repl = lambda m , x : None
958
970
with pytest .raises (TypeError , match = p_err ):
959
- values .str .replace ('a' , repl )
971
+ values .str .replace ('a' , repl , regex = True )
960
972
961
973
repl = lambda m , x , y = None : None
962
974
with pytest .raises (TypeError , match = p_err ):
963
- values .str .replace ('a' , repl )
975
+ values .str .replace ('a' , repl , regex = True )
964
976
965
977
# test regex named groups
966
978
values = Series (['Foo Bar Baz' , NA ])
967
979
pat = r"(?P<first>\w+) (?P<middle>\w+) (?P<last>\w+)"
968
980
repl = lambda m : m .group ('middle' ).swapcase ()
969
- result = values .str .replace (pat , repl )
981
+ result = values .str .replace (pat , repl , regex = True )
970
982
exp = Series (['bAR' , NA ])
971
983
tm .assert_series_equal (result , exp )
972
984
@@ -976,28 +988,39 @@ def test_replace_compiled_regex(self):
976
988
977
989
# test with compiled regex
978
990
pat = re .compile (r'BAD[_]*' )
979
- result = values .str .replace (pat , '' )
991
+ result = values .str .replace (pat , '' , regex = True )
980
992
exp = Series (['foobar' , NA ])
981
993
tm .assert_series_equal (result , exp )
982
994
983
- result = values .str .replace (pat , '' , n = 1 )
995
+ result = values .str .replace (pat , '' , n = 1 , regex = True )
984
996
exp = Series (['foobarBAD' , NA ])
985
997
tm .assert_series_equal (result , exp )
986
998
987
999
# mixed
988
1000
mixed = Series (['aBAD' , NA , 'bBAD' , True , datetime .today (), 'fooBAD' ,
989
1001
None , 1 , 2. ])
990
1002
991
- rs = Series (mixed ).str .replace (pat , '' )
1003
+ rs = Series (mixed ).str .replace (pat , '' , regex = True )
992
1004
xp = Series (['a' , NA , 'b' , NA , NA , 'foo' , NA , NA , NA ])
993
1005
assert isinstance (rs , Series )
994
1006
tm .assert_almost_equal (rs , xp )
995
1007
1008
+ # unicode
1009
+ values = Series ([u'fooBAD__barBAD' , NA ])
1010
+
1011
+ result = values .str .replace (pat , '' , regex = True )
1012
+ exp = Series ([u'foobar' , NA ])
1013
+ tm .assert_series_equal (result , exp )
1014
+
1015
+ result = values .str .replace (pat , '' , n = 1 , regex = True )
1016
+ exp = Series ([u'foobarBAD' , NA ])
1017
+ tm .assert_series_equal (result , exp )
1018
+
996
1019
# flags + unicode
997
1020
values = Series ([b"abcd,\xc3 \xa0 " .decode ("utf-8" )])
998
1021
exp = Series ([b"abcd, \xc3 \xa0 " .decode ("utf-8" )])
999
1022
pat = re .compile (r"(?<=\w),(?=\w)" , flags = re .UNICODE )
1000
- result = values .str .replace (pat , ", " )
1023
+ result = values .str .replace (pat , ", " , regex = True )
1001
1024
tm .assert_series_equal (result , exp )
1002
1025
1003
1026
# case and flags provided to str.replace will have no effect
@@ -1007,29 +1030,30 @@ def test_replace_compiled_regex(self):
1007
1030
1008
1031
with pytest .raises (ValueError ,
1009
1032
match = "case and flags cannot be" ):
1010
- result = values .str .replace (pat , '' , flags = re .IGNORECASE )
1033
+ result = values .str .replace (pat , '' , flags = re .IGNORECASE ,
1034
+ regex = True )
1011
1035
1012
1036
with pytest .raises (ValueError ,
1013
1037
match = "case and flags cannot be" ):
1014
- result = values .str .replace (pat , '' , case = False )
1038
+ result = values .str .replace (pat , '' , case = False , regex = True )
1015
1039
1016
1040
with pytest .raises (ValueError ,
1017
1041
match = "case and flags cannot be" ):
1018
- result = values .str .replace (pat , '' , case = True )
1042
+ result = values .str .replace (pat , '' , case = True , regex = True )
1019
1043
1020
1044
# test with callable
1021
1045
values = Series (['fooBAD__barBAD' , NA ])
1022
1046
repl = lambda m : m .group (0 ).swapcase ()
1023
1047
pat = re .compile ('[a-z][A-Z]{2}' )
1024
- result = values .str .replace (pat , repl , n = 2 )
1048
+ result = values .str .replace (pat , repl , n = 2 , regex = True )
1025
1049
exp = Series (['foObaD__baRbaD' , NA ])
1026
1050
tm .assert_series_equal (result , exp )
1027
1051
1028
1052
def test_replace_literal (self ):
1029
1053
# GH16808 literal replace (regex=False vs regex=True)
1030
1054
values = Series (['f.o' , 'foo' , NA ])
1031
1055
exp = Series (['bao' , 'bao' , NA ])
1032
- result = values .str .replace ('f.' , 'ba' )
1056
+ result = values .str .replace ('f.' , 'ba' , regex = True )
1033
1057
tm .assert_series_equal (result , exp )
1034
1058
1035
1059
exp = Series (['bao' , 'foo' , NA ])
@@ -2726,6 +2750,7 @@ def test_partition_deprecation(self):
2726
2750
result = values .str .rpartition (pat = '_' )
2727
2751
tm .assert_frame_equal (result , expected )
2728
2752
2753
+ @pytest .mark .filterwarnings ("ignore: '|' is interpreted as a literal" )
2729
2754
def test_pipe_failures (self ):
2730
2755
# #2119
2731
2756
s = Series (['A|B|C' ])
@@ -2735,7 +2760,7 @@ def test_pipe_failures(self):
2735
2760
2736
2761
tm .assert_series_equal (result , exp )
2737
2762
2738
- result = s .str .replace ('|' , ' ' )
2763
+ result = s .str .replace ('|' , ' ' , regex = None )
2739
2764
exp = Series (['A B C' ])
2740
2765
2741
2766
tm .assert_series_equal (result , exp )
@@ -2996,17 +3021,17 @@ def test_replace_moar(self):
2996
3021
s = Series (['A' , 'B' , 'C' , 'Aaba' , 'Baca' , '' , NA , 'CABA' ,
2997
3022
'dog' , 'cat' ])
2998
3023
2999
- result = s .str .replace ('A' , 'YYY' )
3024
+ result = s .str .replace ('A' , 'YYY' , regex = True )
3000
3025
expected = Series (['YYY' , 'B' , 'C' , 'YYYaba' , 'Baca' , '' , NA ,
3001
3026
'CYYYBYYY' , 'dog' , 'cat' ])
3002
3027
assert_series_equal (result , expected )
3003
3028
3004
- result = s .str .replace ('A' , 'YYY' , case = False )
3029
+ result = s .str .replace ('A' , 'YYY' , case = False , regex = True )
3005
3030
expected = Series (['YYY' , 'B' , 'C' , 'YYYYYYbYYY' , 'BYYYcYYY' , '' , NA ,
3006
3031
'CYYYBYYY' , 'dog' , 'cYYYt' ])
3007
3032
assert_series_equal (result , expected )
3008
3033
3009
- result = s .str .replace ('^.a|dog' , 'XX-XX ' , case = False )
3034
+ result = s .str .replace ('^.a|dog' , 'XX-XX ' , case = False , regex = True )
3010
3035
expected = Series (['A' , 'B' , 'C' , 'XX-XX ba' , 'XX-XX ca' , '' , NA ,
3011
3036
'XX-XX BA' , 'XX-XX ' , 'XX-XX t' ])
3012
3037
assert_series_equal (result , expected )
@@ -3177,6 +3202,40 @@ def test_method_on_bytes(self):
3177
3202
with pytest .raises (TypeError , match = "can't concat str to bytes" ):
3178
3203
lhs .str .cat (rhs )
3179
3204
3205
+ @pytest .mark .filterwarnings ("ignore: '.' is interpreted as a literal" )
3206
+ @pytest .mark .parametrize ("regex, expected_array" , [
3207
+ (True , ['foofoofoo' , 'foofoofoo' ]),
3208
+ (False , ['abc' , '123' ]),
3209
+ (None , ['abc' , '123' ])
3210
+ ])
3211
+ def test_replace_single_pattern (self , regex , expected_array ):
3212
+ values = Series (['abc' , '123' ])
3213
+ # GH: 24804
3214
+ result = values .str .replace ('.' , 'foo' , regex = regex )
3215
+ expected = Series (expected_array )
3216
+ tm .assert_series_equal (result , expected )
3217
+
3218
+ @pytest .mark .parametrize ("input_array, single_char, replace_char, "
3219
+ "expect_array, warn" ,
3220
+ [("a.c" , "." , "b" , "abc" , True ),
3221
+ ("a@c" , "@" , "at" , "aatc" , False )]
3222
+ )
3223
+ def test_replace_warning_single_character (self , input_array ,
3224
+ single_char , replace_char ,
3225
+ expect_array , warn ):
3226
+ # GH: 24804
3227
+ values = Series ([input_array ])
3228
+ if warn :
3229
+ with tm .assert_produces_warning (FutureWarning ,
3230
+ check_stacklevel = False ):
3231
+ result = values .str .replace (single_char , replace_char )
3232
+ else :
3233
+ result = values .str .replace (single_char , replace_char )
3234
+
3235
+ expected = Series ([expect_array ])
3236
+ tm .assert_series_equal (result , expected )
3237
+
3238
+ @pytest .mark .skipif (compat .PY2 , reason = 'not in python2' )
3180
3239
def test_casefold (self ):
3181
3240
# GH25405
3182
3241
expected = Series (['ss' , NA , 'case' , 'ssd' ])
0 commit comments