www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - chaining splitters

reply "dnoob" <Flamencofantasy gmail.com> writes:
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!
Mar 10 2015
next sibling parent "Dennis Ritchie" <dennis.ritchie mail.ru> writes:
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); } }
Mar 10 2015
prev sibling next sibling parent ketmar <ketmar ketmar.no-ip.org> writes:
On Wed, 11 Mar 2015 00:00:38 +0000, dnoob wrote:

 Hello,
=20
 I am parsing some text and I have the following;
=20
 string text =3D "some very long text";
=20
 foreach(line; splitter(text, [13, 10]))
 {
 	foreach(record; splitter(line, '*'))
 	{
 		foreach(field; splitter(record, '=3D'))
 		{
 			foreach(value; splitter(field, ','))
 			{
 				// do something...
 			}
 		}
 	}
 }
=20
 I know there is a better way to do that but I'm a total D noob.
=20
 Thanks!
it depends of the thing you want to do. please, describe your task, as=20 the solutions can differ depending of your needs. if you needs only=20 values and don't care about everything other, this can help: import std.regex; import std.stdio; void main () { string text =3D "some,very=3Dlong,text*another=3Dshit"; foreach (immutable v; text.splitter(regex("[,=3D*\n\r]"))) { writeln(v); } } =
Mar 11 2015
prev sibling next sibling parent reply "Dave S" <wrrx11 gmail.com> writes:
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.
Mar 11 2015
parent "dnoob" <crayolist gmail.com> writes:
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.
Mar 12 2015
prev sibling parent "Baz" <bb.temp gmx.com> writes:
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; } ---
Mar 11 2015