查找任意项中出现的所有元组

Find all tuple occurrences in arbitrary term

我有一个包含未知的结构良好的 erlang 数据的任意术语。我需要在该术语的任何位置找到所有出现的元组 {atom, _} 。

模式匹配依赖于知道哪个结构包含您的数据,但我不知道。

我需要从中提取的示例

  [
    {description, ""},
    {applications, [
      kernel,
      stdlib,
      ssl
    ]},
    {env, [
      {is_enabled, true},
      {jos, {atom, "2o3urglk3ugr"}},
      {fss_pool, {
        [
          {ja, 10}
        ],
        [
          {host, {atom, "fkejbkjfb"}},
          {port, 6000}
        ]}
      }
    ]}
  ]}.

是否有通用的模式匹配方式遍历任意词条?

不是真的。您必须特别对待要遍历的每种数据结构。类似于:

traverse({atom, Value}) ->
    %% found it!
    [{atom, Value}];
traverse(List) when is_list(List) ->
    lists:flatmap(fun traverse/1, List);
traverse(Tuple) when is_tuple(Tuple) ->
    lists:flatmap(fun traverse/1, tuple_to_list(Tuple));
traverse(Map) when is_map(Map) ->
    lists:flatmap(fun traverse/1, maps:to_list(Map));
traverse(_Other) ->
    %% not the value we're looking for
    [].

这不是一个完整的答案,因为我刚刚安装了 OTP 22.0,但您可以将上面提到的值转换为二进制,然后使用 RE 找到所有需要的匹配项。

例如:

X = ...,
B  = term_to_binary(X),
{ok, MP} = re:compile(<<"atom">>, [extended]),
{match, Res} = re:run(B, MP, [{capture, all, index}]),
ok = io:fwrite("BX: ~p ~p~n ~p", [B, MP, Res]).

re:compile 和 re:run 的选项并不完全符合您的要求,正则表达式本身应扩展为包含原子后的值 :/

(由于时间限制,我无法给出复制和粘贴的答案,但我做了一些类似于解析来自另一个程序的文本日志并找到我需要的东西。我希望这会为你指出另一个可选的 work-through。 )