I am trying to write a Julia function that performs a find and replace operation on each element in an array of strings using regular expressions. It is essentially a wrapper around a broadcasted replace()
call. If you are familiar with R's stringr package, this function should more or less work the same as stringr::str_replace_all()
.
The code below replaces all instances of 'ee' with 'EE', replacing "greetings" with "grEEtings":
arr = ["hi", "hello", "welcome", "greetings"]
replace.(arr, r"e{2}" => "EE")
The function I wrote does not replace any values in array arr:
function str_replace_all(string::String, pattern::String, replacement::String)
replace.(string, Regex(pattern) => replacement)
end
str_replace_all(arr, "e{2}", "EE")
What went wrong? Thanks!
CodePudding user response:
drop type annotations in your function and it should work:
julia> arr = ["hi", "hello", "welcome", "greetings"]
julia> function str_replace_all(string, pattern, replacement)
replace.(string, Regex(pattern) => replacement)
end
CodePudding user response:
You have to actually modify the array:
function str_replace_all!(arr, pattern, replacement)
arr .= replace.(arr, pattern => replacement)
end
You should put a !
at the end of the function name to signal that it mutates the input. That is only a convention, it has no effect, but you should follow it nonetheless.
CodePudding user response:
The code you provided does not yet run, since you are trying to pass a String, but your function expects an Array of Strings. You either have to:
Remove the type annotation of
string::String
in the function definition, orvectorize your function when calling it, using the '.' syntax:
str_replace_all.(arr, "e{2}", "EE")
It should also be noted that your function will not replace strings in the array, it will create a new array containing the replaced values. If you want to get the replaced values in your array, you could do something like:
function str_replace_all(string, pattern::String, replacement::String)
replace.(string, Regex(pattern) => replacement)
end
arr = str_replace_all(arr, "e{2}", "EE")
CodePudding user response:
After incorporating feedback from everyone's answers, here is my solution:
function str_replace_all(string::String, pattern::String, replacement::String)
replace(string, pattern => replacement)
end
function str_replace_all(string::String, pattern::Regex, replacement::String)
replace(string, pattern => replacement)
end
It is best to take advantage of multiple dispatch to allow users to decide on the type of pattern to send to replace()
--an exact match (string) or a regular expression. Further, vectorization of the solution should be done when calling the function (e.g. str_replace_all.()
) instead of being placed inside the function's body (as was the case with the call to replace.()
in the OP).
Ex:
arr = ["hi", "hello", "welcome", "greetings"]
str_replace_all.(arr, "ee", "EE")
str_replace_all.(arr, r"e{2}", "EE")