gpt4 book ai didi

string - Elixir String.split/3 : how to tell which character was matched

转载 作者:行者123 更新时间:2023-12-03 21:47:59 25 4
gpt4 key购买 nike

我正在尝试使用 String.split/3 构建一个解析器作为练习,只是为了看看我是否可以让它比经典的递归模式匹配更快(通过有效地分配更少的字符串),但是我无法使其正确。

我需要能够在 {}String.split(str, ["{", "}"], parts: 2) 当然是这样做的。我的问题是结果只包含列表 [part1, part2] 但它不包含它匹配的字符,我需要它,因为它会影响解析器的行为。

我的第一直觉是制作我自己的 index/2 但在阅读更多之后它 seemsbad idea

我的用例是否有更好的替代方案?我想尽可能少地遍历字符串,只在 {} 边界创建新字符串。

感谢阅读!

最佳答案

因为你只想在第一次出现时拆分,我建议在这里使用 :binary.match/3:binary.part/3:binary.match/3 返回匹配索引和成功匹配长度的元组,然后可以与 :binary.part/2 一起使用来拆分二进制文件。

defmodule A do
def split(binary) do
case :binary.match(binary, ["{", "}"]) do
{start, length} ->
before = :binary.part(binary, 0, start)
match = :binary.part(binary, start, length)
after_ = :binary.part(binary, start + length, byte_size(binary) - (start + length))
{before, match, after_}
:nomatch -> nil
end
end
end

IO.inspect A.split("foo { bar") |> IO.inspect
IO.inspect A.split("foo } bar") |> IO.inspect
IO.inspect A.split("foo + bar") |> IO.inspect

输出:

{"foo ", "{", " bar"}
{"foo ", "{", " bar"}
{"foo ", "}", " bar"}
{"foo ", "}", " bar"}
nil
nil

此实现仅在 :binary.match/3 调用中遍历字符串一次。使用的所有其他函数和操作都是 O(1)

我在我正在使用的 XML 解析器中使用了类似的方法,与二进制上的递归模式匹配相比,它提供了巨大的速度。

编辑:您可以使用模式匹配来缩短这段代码,我很确定其性能与上面完全相同:

defmodule A do
def split(binary) do
case :binary.match(binary, ["{", "}"]) do
{start, length} ->
<<a::binary-size(start), b::binary-size(length), c::binary>> = binary
{a, b, c}
:nomatch -> nil
end
end
end

关于string - Elixir String.split/3 : how to tell which character was matched,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44112857/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com