Thread overview
chaining splitters
Mar 11, 2015
dnoob
Mar 11, 2015
Dennis Ritchie
Mar 11, 2015
ketmar
Mar 11, 2015
Dave S
Mar 13, 2015
dnoob
Mar 11, 2015
Baz
March 11, 2015
Hello,

I am parsing some text and I have the following;

string text = "some very long text";

foreach(line; splitter(text, [13, 10]))
{
	foreach(record; splitter(line, '*'))
	{
		foreach(field; splitter(record, '='))
		{
			foreach(value; splitter(field, ','))
			{
				// do something...
			}
		}
	}
}

I know there is a better way to do that but I'm a total D noob.

Thanks!

March 11, 2015
On Wednesday, 11 March 2015 at 00:00:39 UTC, dnoob wrote:
> Hello,
>
> I am parsing some text and I have the following;
>
> string text = "some very long text";
>
> foreach(line; splitter(text, [13, 10]))
> {
> 	foreach(record; splitter(line, '*'))
> 	{
> 		foreach(field; splitter(record, '='))
> 		{
> 			foreach(value; splitter(field, ','))
> 			{
> 				// do something...
> 			}
> 		}
> 	}
> }
>
> I know there is a better way to do that but I'm a total D noob.
>
> Thanks!

I don't understand what you want to do. Maybe you want to do this:

import std.stdio;
import std.string;

void main() {

	string text = "some very long text";
	
	foreach(line; text.split) {
		writeln(line);
	}
}
March 11, 2015
On Wed, 11 Mar 2015 00:00:38 +0000, dnoob wrote:

> Hello,
> 
> I am parsing some text and I have the following;
> 
> string text = "some very long text";
> 
> foreach(line; splitter(text, [13, 10]))
> {
> 	foreach(record; splitter(line, '*'))
> 	{
> 		foreach(field; splitter(record, '='))
> 		{
> 			foreach(value; splitter(field, ','))
> 			{
> 				// do something...
> 			}
> 		}
> 	}
> }
> 
> I know there is a better way to do that but I'm a total D noob.
> 
> Thanks!

it depends of the thing you want to do. please, describe your task, as the solutions can differ depending of your needs. if you needs only values and don't care about everything other, this can help:

  import std.regex;
  import std.stdio;

  void main () {
    string text = "some,very=long,text*another=shit";
    foreach (immutable v; text.splitter(regex("[,=*\n\r]"))) {
      writeln(v);
    }
  }


March 11, 2015
On Wednesday, 11 March 2015 at 00:00:39 UTC, dnoob wrote:
> Hello,
>
> I am parsing some text and I have the following;
>
> string text = "some very long text";
>
> foreach(line; splitter(text, [13, 10]))
> {
> 	foreach(record; splitter(line, '*'))
> 	{
> 		foreach(field; splitter(record, '='))
> 		{
> 			foreach(value; splitter(field, ','))
> 			{
> 				// do something...
> 			}
> 		}
> 	}
> }
>
> I know there is a better way to do that but I'm a total D noob.
>
> Thanks!

You can use std.algorithm's map to apply some function to all the
items in a range:
---

import std.stdio, std.algorithm;

void main()
{
	string text = "foo*bar=qux\r\nHello*world!\r\nApril,May,June";

	auto lines = splitter(text, "\r\n");
	auto records = map!(a => splitter(a, '*'))(lines).joiner();
	auto fields = map!(a => splitter(a, '='))(records).joiner();
	auto values = map!(a => splitter(a, ','))(fields).joiner();

	foreach (value; values)
	{
		writeln(value);
	}
}

---
This produces the output:

foo
bar
qux
Hello
world!
April
May
June

The joiner() is necessary because when you pass a range of
strings to splitter using map the result is a range of ranges of
strings. joiner() joins these together into one range of strings.
Consider this code, for example:
---

string str = "foo*bar=qux\r\nHello*world!\r\nApril,May,June";

auto lines = splitter(str, [13, 10]);
auto result = map!(a => splitter(a, '*'))(lines);
auto tokens = result.joiner();

---
The contents of result are:

["foo", "bar=qux"]
["Hello", "world!"]
["April,May,June"]

The contents of tokens are:

["foo", "bar=qux", "Hello", "world!", "April,May,June"]

I am not a D expert by any means so there it's possible there is
another way that I am not aware of.
March 11, 2015
On Wednesday, 11 March 2015 at 00:00:39 UTC, dnoob wrote:
> Hello,
>
> I am parsing some text and I have the following;
>
> string text = "some very long text";
>
> foreach(line; splitter(text, [13, 10]))
> {
> 	foreach(record; splitter(line, '*'))
> 	{
> 		foreach(field; splitter(record, '='))
> 		{
> 			foreach(value; splitter(field, ','))
> 			{
> 				// do something...
> 			}
> 		}
> 	}
> }
>
> I know there is a better way to do that but I'm a total D noob.
>
> Thanks!

For this kind of things i tend to write a small lexer because you have a good control on what to do where to do it and the finally the pattern is quite simple:
---
// empty/front/popFront for build-in arrays
import std.array;

string identifier;
while (!text.empty)
{
  auto current = text.front;
  //
  // test whites/memorize identifier/resetidentifier
  // test punctuation/reset identifier...
  // test keywords/reset identifier...
  identifier ~= current;
  text.popFront;
}
---
March 13, 2015
Yes. That's it! Thanks a lot.


On Wednesday, 11 March 2015 at 09:29:12 UTC, Dave S wrote:
> On Wednesday, 11 March 2015 at 00:00:39 UTC, dnoob wrote:
>> Hello,
>>
>> I am parsing some text and I have the following;
>>
>> string text = "some very long text";
>>
>> foreach(line; splitter(text, [13, 10]))
>> {
>> 	foreach(record; splitter(line, '*'))
>> 	{
>> 		foreach(field; splitter(record, '='))
>> 		{
>> 			foreach(value; splitter(field, ','))
>> 			{
>> 				// do something...
>> 			}
>> 		}
>> 	}
>> }
>>
>> I know there is a better way to do that but I'm a total D noob.
>>
>> Thanks!
>
> You can use std.algorithm's map to apply some function to all the
> items in a range:
> ---
>
> import std.stdio, std.algorithm;
>
> void main()
> {
> 	string text = "foo*bar=qux\r\nHello*world!\r\nApril,May,June";
>
> 	auto lines = splitter(text, "\r\n");
> 	auto records = map!(a => splitter(a, '*'))(lines).joiner();
> 	auto fields = map!(a => splitter(a, '='))(records).joiner();
> 	auto values = map!(a => splitter(a, ','))(fields).joiner();
>
> 	foreach (value; values)
> 	{
> 		writeln(value);
> 	}
> }
>
> ---
> This produces the output:
>
> foo
> bar
> qux
> Hello
> world!
> April
> May
> June
>
> The joiner() is necessary because when you pass a range of
> strings to splitter using map the result is a range of ranges of
> strings. joiner() joins these together into one range of strings.
> Consider this code, for example:
> ---
>
> string str = "foo*bar=qux\r\nHello*world!\r\nApril,May,June";
>
> auto lines = splitter(str, [13, 10]);
> auto result = map!(a => splitter(a, '*'))(lines);
> auto tokens = result.joiner();
>
> ---
> The contents of result are:
>
> ["foo", "bar=qux"]
> ["Hello", "world!"]
> ["April,May,June"]
>
> The contents of tokens are:
>
> ["foo", "bar=qux", "Hello", "world!", "April,May,June"]
>
> I am not a D expert by any means so there it's possible there is
> another way that I am not aware of.