-1

I am working on some Elixir coding challenge that requires Regex solution and encountered this following code:

defmodule Solution do
  def remove(some_string)
    String.replace(some_string, ~r/!(?!!*$)/, "")
  end
end

Solution.remove("!Hi!!!") #=> "Hi!!!"
Solution.remove("Hi!") #=> "Hi!"
Solution.remove("Hi") #=> "Hi"

It removes exclamation mark that are not at the end.

My question is, I do not understand what /!(?!!*$)/ line does. I believe this part of Regex is not Elixir-specific. I know that !*$ means that zero or more ! at the end of the String. What does the entire regex do in plain English?

Additionally:

What does ?!... do? (I thought ? means zero or more, but why is it before an exclamation mark?)

Why is there an exclamation mark before the parentheses !(...?

sneep
  • 1,828
  • 14
  • 19
Iggy
  • 5,129
  • 12
  • 53
  • 87

1 Answers1

2

It's negative look-ahead. Maybe check out https://www.regular-expressions.info/lookaround.html, which explains it all very nicely. It's also been covered on this site, of course, but I'd imagine searching for '?!' doesn't always yield results: Understanding negative lookahead

So in plain English it's "!" not followed by "!*$", where these characters mean exactly what you wrote above.

sneep
  • 1,828
  • 14
  • 19