说我有一个字符串,例如s = "abcdé"
,我想将其截断为许多 bytes ,在本例中为五(5)。但是,由于最后一个“字形”由多个字节组成,所以我想byte_truncate_nicely(s, 5) == "abcd"
是正确的,因为这似乎不明智,例如使用binary_part
,然后分割最终的字素。
答案 0 :(得分:3)
我不知道这样的功能是否存在,但是您可以自己编写
bytes_number = 5
"abcdé"
|> String.split("")
|> Enum.reduce_while("",
fn char, acc ->
if byte_size(acc <> char) <= bytes_number do
{:cont, acc <> char}
else
{:halt, acc}
end
end)
答案 1 :(得分:2)
我认为没有内置方法可以执行此操作,但是您可以手动完成。
def take_bytes(str, limit) do
str
|> String.graphemes()
|> Enum.reduce({[], 0}, fn g, {acc, sum} ->
next_size = byte_size(g)
if sum + next_size > limit do
{acc, sum}
else
{[g | acc], sum + next_size}
end
end)
|> elem(0)
|> Enum.join()
end
如果将字符串转换为字素,则可以测量它们占用了多少字节。然后,只需要“吃”出尽可能多的字素即可。
示例:
iex(1)> byte_size("á̀̃é̀̃")
14
iex(2)> T.take_bytes("á̀̃é̀̃", 6)
""
iex(3)> T.take_bytes("á̀̃é̀̃", 7)
"á̀̃"
iex(4)> T.take_bytes("á̀̃é̀̃", 14)
"é̀̃á̀̃"
iex(5)> T.take_bytes("á̀̃é̀̃", 13)
"á̀̃"
答案 2 :(得分:0)
只是出于好奇:
for <<c :: utf8 <- "abcdé">>, reduce: "" do
acc when byte_size(acc <> <<c :: utf8>>) <= 5 ->
acc <> <<c :: utf8>>
acc ->
acc
end
#⇒ "abcd"
或者,甚至更好(但不太正确):
for <<c <- "abcdé">>,
reduce: "",
do: (acc when c < 128 -> acc <> <<c>>; acc -> acc)
#⇒ "abcd"
for <<c <- "abcde">>,
reduce: "",
do: (acc when c < 128 -> acc <> <<c>>; acc -> acc)
#⇒ "abcde"
NB 这个结果无法产生正确的结果,以及此处发布的其他两个答案;主要是因为没有针对所述问题的正确答案。