Elixir/Erlang 如何在换行符处拆分二进制字符串?

12

有没有一种方法可以将从文件加载的比特串按换行符分割?我有类似这样的东西:

A line of text
Additional line of text
And another line

我想要一个像这样的数组:

["A line of text",
"Additional line of text",
"And another line"]

是否有函数可以将文本按照换行符分割成类似于这样的数组?

提前致谢。

5个回答

18

除了Robert的回答之外,在Elixir中你可以使用:String.split(string, "\n") 请查看String模块。


10

看看binary模块中的binary:split/2/3函数。例如,使用binary:split(String, <<"\n">>)


在这种简单的情况下,您也可以使用 re,但这是过度杀伤力。 - rvirding

5
如果你只是简单地以\n为分隔符来拆分字符串,那么就会存在一些严重的可移植性问题。这是因为许多系统使用\n,而一些旧版的 Mac 使用\r,而 Windows 使用\r\n 来分隔新行。
更安全的方法是使用正则表达式来匹配上述三种可能性之一:String.split(str, ~r{(\r\n|\r|\n)}

2
虽然想法是正确的,但在您的正则表达式中有一个额外的反斜杠,在第一个 | 字符之前。这是正确的版本:String.split("foo\r\nbar", ~r{\r\n|\r|\n}) - nietaki
没错,我已经编辑了答案以删除打字错误。谢谢! - Mark Wilbur

4

虽然Mark提到了可移植性问题,但是他提供的正则表达式中有一个错字,因此不能处理\r\n序列。以下是一个更简单的版本,可以处理所有3种情况:

iex(13)> String.split("foo\nbar", ~r/\R/)
["foo", "bar"]
iex(14)> String.split("foo\rbar", ~r/\R/)
["foo", "bar"]
iex(15)> String.split("foo\r\nbar", ~r/\R/)
["foo", "bar"]

2
我最近遇到了一种情况,其中我的另一个答案中的解决方案和任何其他依赖于正则表达式的解决方案在某些情况下比依赖于二进制分割要慢得多,特别是当限制字符串被分割成的部分数量时。您可以查看https://github.com/CrowdHailer/server_sent_event.ex/pull/11以获取更详细的分析和基准测试。
即使针对不同类型的换行符,您也可以使用:binary.split/3
iex(1)> "aaa\rbbb\nccc\r\nddd" |> :binary.split(["\r", "\n", "\r\n"], [:global])     
["aaa", "bbb", "ccc", "ddd"]

正如您在上面的示例中所看到的,匹配是贪婪的,\r\n 优先于首先通过 \r 进行拆分,然后再通过 \n 进行拆分。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接