Thread overview
How to split a string/array with multiple separators?
Dec 16, 2015
Borislav Kosharov
Dec 16, 2015
Dragos Carp
Dec 16, 2015
Marc Schütz
May 12, 2016
Thorsten Sommer
May 13, 2016
Thorsten Sommer
May 14, 2016
Joel
December 16, 2015
I want to split a string using multiple separators. In std.array the split function has a version where it takes a range as a separator, but it works differently than what I want. Say if I call it with " -> " it will search for the whole thing together. I want to pass split a list of separators say [":", ",", ";"] and if it finds any of those to split it.

Sorry if this questions is stupid but I cant find how to do it.
December 16, 2015
On Wednesday, 16 December 2015 at 14:18:28 UTC, Borislav Kosharov wrote:
> I want to split a string using multiple separators. In std.array the split function has a version where it takes a range as a separator, but it works differently than what I want. Say if I call it with " -> " it will search for the whole thing together. I want to pass split a list of separators say [":", ",", ";"] and if it finds any of those to split it.
>
> Sorry if this questions is stupid but I cant find how to do it.


void main()
{

   import std.stdio: writeln;
   writeln("abc,def;ghi".splitter!(a => !":,;".find(a).empty).array);
}
December 16, 2015
On Wednesday, 16 December 2015 at 14:47:26 UTC, Dragos Carp wrote:
> On Wednesday, 16 December 2015 at 14:18:28 UTC, Borislav Kosharov wrote:
>> I want to split a string using multiple separators. In std.array the split function has a version where it takes a range as a separator, but it works differently than what I want. Say if I call it with " -> " it will search for the whole thing together. I want to pass split a list of separators say [":", ",", ";"] and if it finds any of those to split it.
>>
>> Sorry if this questions is stupid but I cant find how to do it.
>
>
> void main()
> {
>
>    import std.stdio: writeln;
>    writeln("abc,def;ghi".splitter!(a => !":,;".find(a).empty).array);
> }

The call to `array` is unnecessary in this example, and you can use the shorter `canFind`:

   writeln("abc,def;ghi".splitter!(a => ":,;".canFind(a)));
May 12, 2016
On Wednesday, 16 December 2015 at 15:27:22 UTC, Marc Schütz wrote:
> On Wednesday, 16 December 2015 at 14:47:26 UTC, Dragos Carp wrote:
>> On Wednesday, 16 December 2015 at 14:18:28 UTC, Borislav Kosharov wrote:
>>> I want to split a string using multiple separators. In std.array the split function has a version where it takes a range as a separator, but it works differently than what I want. Say if I call it with " -> " it will search for the whole thing together. I want to pass split a list of separators say [":", ",", ";"] and if it finds any of those to split it.
>>>
>>> Sorry if this questions is stupid but I cant find how to do it.
>>
>>
>> void main()
>> {
>>
>>    import std.stdio: writeln;
>>    writeln("abc,def;ghi".splitter!(a => !":,;".find(a).empty).array);
>> }
>
> The call to `array` is unnecessary in this example, and you can use the shorter `canFind`:
>
>    writeln("abc,def;ghi".splitter!(a => ":,;".canFind(a)));


Dear Borislav, Dragos and Marc,

Thanks for this question (@Borislav) and the solution's approaches (@Dragos and @Marc). Today, I had the same task and tried to find a solution for it. Unfortunately, the proposed solutions seem not work.

Here is the version from Dragos (run it directly on the web):
http://ideone.com/fglk0s

Here the version from Marc:
http://ideone.com/yCaYrD

In both cases, I got the "Error: template std.algorithm.iteration.splitter cannot deduce function from argument types [...]" message.

Can anyone help me with a functional example? That would be great :)


Best regards,
Thorsten
May 12, 2016
On 5/12/16 3:25 PM, Thorsten Sommer wrote:
> On Wednesday, 16 December 2015 at 15:27:22 UTC, Marc Schütz wrote:
>> On Wednesday, 16 December 2015 at 14:47:26 UTC, Dragos Carp wrote:
>>> On Wednesday, 16 December 2015 at 14:18:28 UTC, Borislav Kosharov wrote:
>>>> I want to split a string using multiple separators. In std.array the
>>>> split function has a version where it takes a range as a separator,
>>>> but it works differently than what I want. Say if I call it with "
>>>> -> " it will search for the whole thing together. I want to pass
>>>> split a list of separators say [":", ",", ";"] and if it finds any
>>>> of those to split it.
>>>>
>>>> Sorry if this questions is stupid but I cant find how to do it.
>>>
>>>
>>> void main()
>>> {
>>>
>>>    import std.stdio: writeln;
>>>    writeln("abc,def;ghi".splitter!(a => !":,;".find(a).empty).array);
>>> }
>>
>> The call to `array` is unnecessary in this example, and you can use
>> the shorter `canFind`:
>>
>>    writeln("abc,def;ghi".splitter!(a => ":,;".canFind(a)));
>
>
> Dear Borislav, Dragos and Marc,
>
> Thanks for this question (@Borislav) and the solution's approaches
> (@Dragos and @Marc). Today, I had the same task and tried to find a
> solution for it. Unfortunately, the proposed solutions seem not work.
>
> Here is the version from Dragos (run it directly on the web):
> http://ideone.com/fglk0s
>
> Here the version from Marc:
> http://ideone.com/yCaYrD
>
> In both cases, I got the "Error: template
> std.algorithm.iteration.splitter cannot deduce function from argument
> types [...]" message.
>
> Can anyone help me with a functional example? That would be great :)

You are missing some imported symbols.

Unfortunately, due to the way binaryFun works, this masks the true error (can't compile your lambda!).

https://dpaste.dzfl.pl/79399404f2ad

Note, the ideone compiler is very out of date. But it probably would work with the correct imports.

-Steve
May 13, 2016
Wow, thanks Steve :)
May 14, 2016
On Wednesday, 16 December 2015 at 15:27:22 UTC, Marc Schütz wrote:
> On Wednesday, 16 December 2015 at 14:47:26 UTC, Dragos Carp wrote:
>> On Wednesday, 16 December 2015 at 14:18:28 UTC, Borislav Kosharov wrote:
>>> I want to split a string using multiple separators. In std.array the split function has a version where it takes a range as a separator, but it works differently than what I want. Say if I call it with " -> " it will search for the whole thing together. I want to pass split a list of separators say [":", ",", ";"] and if it finds any of those to split it.
>>>
>>> Sorry if this questions is stupid but I cant find how to do it.
>>
>>
>> void main()
>> {
>>
>>    import std.stdio: writeln;
>>    writeln("abc,def;ghi".splitter!(a => !":,;".find(a).empty).array);
>> }
>
> The call to `array` is unnecessary in this example, and you can use the shorter `canFind`:
>
>    writeln("abc,def;ghi".splitter!(a => ":,;".canFind(a)));

What about "abc,;;.. def" you get empty strings?

I've come up with this:

import std.stdio : writeln;
import std.algorithm : canFind, splitter, filter;

void main() {
	writeln("abc,:def;ghi". // or "abc, def. Ghi"
		splitter!(a => " .,:;".canFind(a)).
		filter!(a => a.length));
}