mruoss
Is there a way to escape escape characters i.e. turn `"\u2003"` => `"\\u2003"`?
Hey, does anybody know if it is possible to escape escape characters like \r or \u2003? Given a string containing such characters, I’d like to turn them into an escaped form as follows:
iex> Magic.escape("\r\u2003")
"\\r\\u2003"
Most Liked
Eiji
All you need to do is to define a list of characters you want to escape and the rest is a simple reduce:
defmodule Example do
@characters_to_escape [?b]
def sample(string) when is_binary(string) do
for <<char::utf8 <- string>>, reduce: "" do
acc -> acc <> maybe_escape(char)
end
end
defp maybe_escape(char) when char in @characters_to_escape do
char
|> Integer.to_string(16)
|> String.pad_leading(4, "0")
|> then(&"\\u" <> &1)
end
defp maybe_escape(char), do: <<char::utf8>>
end
iex> Example.sample("a b c")
"a \\u0062 c"
Eiji
Enum.reject(0x00..0x1F, & &1 in '\n\t')
mruoss
Thank you all for the input and the sparring. @Eiji I guess I was hoping for some well-defined distinction / function to tell “printable” from other unicode chars. But I learned that what needs to be escaped depends very much on the use case. Looking at Jason, there is the :escape option which can be one of 4 possible values, each one escaping more or fewer chars.
I think the problem is that what you are asking for doesn’t make sense.
@adamu Yes, that too, probably! ![]()
Inspired by Jason I ended up with something like the following which works for my case for now (probably needs refinement):
defmodule NotSoMuchMagic do
@escape_chars '\b\f\r\v\"\\'
@escape_char_maping Enum.zip('\b\f\r\v\"\\', 'bfrv"\\')
@unicode_char_mapping 0x00..0x1F |> Enum.reject(&Kernel.in(&1, '\n\t'))
for {src, dst} <- @escape_char_maping do
defp encode_char(unquote(src)), do: [?\\, unquote(dst)]
end
for uchar <- @unicode_char_mapping do
unicode_sequence = List.to_string(:io_lib.format("\\u~4.16.0B", [uchar]))
defp encode_char(unquote(uchar)), do: unquote(unicode_sequence)
end
defp encode_char(char), do: char
def encode(binary) do
iodata = for (<< char::utf8 <- binary >>), do: encode_char(char)
IO.iodata_to_binary(iodata)
end
end
iex> NotSoMuchMagic.encode("\r \t \v \0 \u0028 \u0012")
"\\r \t \\v \\u0000 ( \\u0012"
mruoss
Decide how to encode them. ![]()
benwilson512
If you want to produce “ascii only” yaml and escape everything else that’s fine, but it seems like yaml technically supports the full UTF8 spectrum. My overall point is that I would pick a well known subset of UTF8 like ASCII and then build your filter on top of that. All ASCII chars go in as is, non ascii are use the escaped utf8 form.







