script
April 2, 2018, 8:49am
1
I have a string like this:
"api/v1/contact/request/type"
I wan to replace the last two occurrence of /
to make the string the string lie this:
"api/v1/contact-request-type"
I look up atRegex
methods but didn’t find replacing specific characters
Thanks!
NobbZ
April 2, 2018, 9:04am
2
If this is really about the last "/"
and the number of segments varies, then the following would probably be the easiest:
iex(1)> [a, b|c] = "api/v1/contact/request" |> String.split("/") |> Enum.reverse
["request", "contact", "v1", "api"]
iex(2)> ((c |> Enum.reverse) ++ [b <> "-" <> a]) |> Enum.join("/")
"api/v1/contact-request"
This will raise
though, when there is no slash in the input.
this should work also without slashes, but is a little monster.
Regex.replace(~r/(.+)\/((?:.(?!\/))+)$/, "api/v1/contact/request", "\\1-\\2")
4 Likes
I was having the same idea
iex> Regex.replace ~r/\/(\w*)$/, "api/v1/contact/request", "-\\1"
"api/v1/contact-request"
2 Likes
script
April 2, 2018, 10:12am
5
Thanks for your answer. I just edited the question can you please edit your answer.
NobbZ
April 2, 2018, 10:22am
7
The edited version of your question says “last occurence” but replaces more than one occurence. So I have trouble to actually figure out your exact requirements…
script
April 2, 2018, 10:23am
8
just updated the question. Last two occurences
iex> Regex.replace ~r/\/(\w*)\/(\w*)$/, "api/v1/contact/request", "-\\1-\\2"
"api/v1-contact-request"
BTW after some replies, it would be better to ask a more precise question without changing the topic
You might find this more precise too…
iex> Regex.replace ~r/\/([^\/]*)\/([^\/]*)$/, "api/v1/contact/request", "-\\1-\\2"
"api/v1-contact-request"
1 Like
NobbZ
April 2, 2018, 10:23am
10
It should be easy to adopt my solution then.
script
April 2, 2018, 10:32am
11
Yes I will next time. Thanks.
NobbZ
April 2, 2018, 10:50am
13
Based on my first solution I built something more generic for any given n
:
defmodule Replacer do
def replace_n(str, n, pat, subst) do
{back, front} =
str
|> String.split(pat)
|> Enum.reverse()
|> Enum.split(n)
back = Enum.join(back, subst)
[back | front]
|> Enum.reverse()
|> Enum.join(pat)
end
end
which also does not raise
on mismatch of pat
count:
iex(1)> Replacer.replace_n("api/v1/contact/request/type", 3, "/", "-")
"api/v1/type-request-contact"
iex(2)> Replacer.replace_n("api/v1/contact/request/type", 2, "/", "-")
"api/v1/contact/type-request"
iex(3)> Replacer.replace_n("api/v1/contact/request/type", 1, "/", "-")
"api/v1/contact/request/type"
iex(4)> Replacer.replace_n("api/v1/contact/request/type", 10, "/", "-")
"type-request-contact-v1-api"
edit
And I just realized a bug
To fix that bug change |> Enum.split(n)
to |> Enum.split(n + 1)
.
1 Like
If You like functions… You can create an anonymous one, which replace the last, and apply it multiple time
iex> repl = fn s -> Regex.replace ~r/\/([^\/]*)$/, s, "-\\1" end
iex> "api/v1/contact/request-ok?111=5" |> repl.() |> repl.()
"api/v1-contact-request-ok?111=5"
1 Like