Home > other >  How to replace a string using a wrapper function in Julia
How to replace a string using a wrapper function in Julia

Time:03-21

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:

  1. Remove the type annotation of string::String in the function definition, or

  2. vectorize 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")
  • Related