拆分相邻分隔符的字符串

时间:2016-05-31 00:15:38

标签: erlang

我想用相邻的分隔符分割一个字符串(如果你还记得string:tokens忽略了相邻的分隔符)。

所以我现在有这个:

split(L, C) -> lists:reverse([lists:reverse(X) || X <- split(L, C, [[]])]).

split([], _, Acc) -> Acc;
split([C|T], C, Acc) -> split(T, C, [[]|Acc]);
split([H|T], C, [AH|AT]) -> split(T, C, [[H|AH]|AT]).

输入["12432524,,32453,4"]的返回值恰好为tut6:split("12432524,,32453,4", ",").。我不明白问题是什么。 有人可以指出我吗?

所需的输出为["12432524", "", "32453", "4"]

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:4)

问题是您要将要拆分的字符串的每个字符与整个字符串分隔符进行比较。当你打电话

tut6:split("12432524,,32453,4", ",").

然后在模块中第一次调用split/3

split([$1|"2432524,,32453,4"], ",", [[]]) ...

第一个参数的头部是字符 1,但是你将它与字符串 ","进行比较,当然这绝不会匹配,所以你的输入字符串永远不会分裂。

有几种方法可以解决这个问题:

  • 让调用者传递字符分隔符而不是字符串,如下所示:

    tut6:split(2432524,,32453,4", $,).
    
  • 让调用者传递字符串分隔符,但只使用其第一个字符作为实际分隔符。您可以通过将代码中的split(L,C)更改为

    来实现此目的
    split(L,[C]) ->
        lists:reverse([lists:reverse(X) || X <- split(L, C, [[]])]).
    

    强制使用单个字符分隔符字符串,或

    split(L,[C|_]) ->
        lists:reverse([lists:reverse(X) || X <- split(L, C, [[]])]).
    

    仅使用第一个字符作为分隔符,并忽略任何尾随字符。

  • 让调用者传递一个字符串分隔符,并将字符串中的每个字符视为一个潜在的分隔符。
  • 让调用者传递字符串分隔符并将整个字符串视为分隔符。

您可以使用re:split/3来完成最后一项:

split(L, C) -> re:split(L, C, [{return,list}]).

这段代码并不完全正确,因为它适用于像","这样的简单分隔符,但除非您在分隔符字符串中引用所有正则表达式元字符,否则它将无法正常工作。