Regex.replace with an accumulating value

You can use Regex.scan instead of Regex.replace. Probably not so fast, but it works :slight_smile:

Regex.scan(~r/(.*?>)([^&<]+)(<\/span>)/s, html, capture: :all_but_first)
|> Enum.map_reduce(0, fn [l, c, r], acc ->
  c =
    c
    |> String.split()
    |> Enum.with_index()
    |> Enum.map(fn {char, index} -> "<span id='CHAR-#{index + acc}'>#{char}</span>" end)

  {[l, c, r], acc + length(c)}
end)
|> elem(0)
|> IO.puts()
2 Likes