www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to split a string/array with multiple separators?

reply Borislav Kosharov <boby_dsm abv.bg> writes:
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.
Dec 16 2015
parent reply Dragos Carp <dragoscarp gmail.com> writes:
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); }
Dec 16 2015
parent reply Marc =?UTF-8?B?U2Now7x0eg==?= <schuetzm gmx.net> writes:
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)));
Dec 16 2015
next sibling parent reply Thorsten Sommer <vektoren gmail.com> writes:
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
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
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 12 2016
parent Thorsten Sommer <vektoren gmail.com> writes:
Wow, thanks Steve :)
May 13 2016
prev sibling parent Joel <joelcnz gmail.com> writes:
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)); }
May 13 2016