Erlang中控制字符转义的正确方法是什么?
解决Erlang中\a控制字符转义问题
你遇到的这个问题其实是因为Erlang的io_lib:format/2里的~p格式化选项,对控制字符的转义支持是有限的——它只会自动转义几个常见的控制字符(比如\t、\n、\r),像\a(ASCII 7,响铃符)这类不在默认转义列表里的字符,要么会被当成不可见字符直接输出,要么当字符串里只有这类非打印字符时,会被转换成字符码的列表形式,这显然不是你想要的效果。
要实现把\a转义成\\a,并且写入文件后显示为"str\aing"的目标,我们可以自己写一个自定义的控制字符转义函数,手动处理所有需要转义的字符:
escape_control_chars(Str) -> lists:flatmap(fun ($\a) -> "\\a"; ($\b) -> "\\b"; ($\f) -> "\\f"; ($\n) -> "\\n"; ($\r) -> "\\r"; ($\t) -> "\\t"; ($\v) -> "\\v"; (C) when C < 32; C == 127 -> % 对其他未定义的控制字符,转成十六进制形式,比如\x07 io_lib:format("\\x~2.16.0b", [C]); (C) -> [C] end, Str).
这个函数会遍历输入字符串的每个字符,把指定的控制字符替换成对应的转义序列,其他不可打印的控制字符则转成\xXX的十六进制格式,可打印字符直接保留。
接下来你可以这样使用这个函数:
% 原始字符串包含\a OriginalStr = "str\aing", % 转义控制字符 EscapedStr = escape_control_chars(OriginalStr), % 如果需要添加引号(和~p的输出格式一致) QuotedStr = "\"" ++ EscapedStr ++ "\"", % 写入文件 file:write_file("output.txt", QuotedStr).
执行这段代码后,output.txt里的内容就是"str\aing",完全符合你的需求。
如果你只需要处理\a这一个字符,也可以简化函数,只保留($\a) -> "\\a";这一行和默认的字符处理逻辑,不过上面的函数可以覆盖更多控制字符的转义场景,实用性更强。
内容的提问来源于stack exchange,提问作者Анна Мухаррам




