当我使用re:像这样替换时,NUL字符不会被替换,但是Replacement将在每个字符之前插入:
1> S = [97, 0, 98].
[97,0,98]
2> R = re:replace(S, "\x00", " ", [global, {return, list}]).
[32,97,32,0,32,98,32]
我希望 R 为 [97,32,98] 。这个表达有什么不对?如何在Erlang中替换字符串中的NUL字符(\ x00)?
答案 0 :(得分:3)
只要您将单个字符替换为另一个字符,lists:map
可能会更简单:
R = lists:map(fun(0) -> 32; (C) -> C end, S).
我怀疑re:replace
的行为是因为它调用PCRE库,它以某种方式处理其中包含NUL字符的字符串。如果您尝试用空格全局替换空字符串,那么您得到的结果就是您所期望的。
答案 1 :(得分:1)
PCRE可以对二进制数据进行操作(即嵌入的空字符)。但是,传递给PCRE的正则表达式模式必须是字符串。当你在Erlang中说“\ x00”时,就像[0],它在正则表达式字符串中嵌入了一个空字节。因此,就PCRE而言,你只是告诉它应该使用的模式是一个空字符串,它匹配所有内容。
幸运的是,使用PCRE很容易处理。 PCRE本身理解\ x表示法,这意味着如果你传递它\ x00,它将匹配空字节。由于反斜杠对Erlang是特殊的,因此必须将其转义:“\\ x00”。
1> S = [97, 0, 98].
[97,0,98]
2> R = re:replace(S, "\\x00", " ", [global, {return, list}]).
"a b"
答案 2 :(得分:0)
字符串是PCRE理解的,特别是字符串的C概念,其中0被视为终结符。列表是Erlang所理解的,"字符串"成员名单来自一组特殊的价值观。
PCRE库似乎将你的正则表达式视为每个字符串之间的含义""和您的列表作为字符串列表,而不是字符。因此,它有效地将您的列表与您提供的值分开,这不是您想要的。 legoscia的解决方案(将输入视为列表而不是"字符串")可能是最强大的选择。