Thread overview |
---|
March 11, 2015 chaining splitters | ||||
---|---|---|---|---|
| ||||
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 Re: chaining splitters | ||||
---|---|---|---|---|
| ||||
Posted in reply to dnoob | 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 Re: chaining splitters | ||||
---|---|---|---|---|
| ||||
Posted in reply to dnoob Attachments: | 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 Re: chaining splitters | ||||
---|---|---|---|---|
| ||||
Posted in reply to dnoob | 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 Re: chaining splitters | ||||
---|---|---|---|---|
| ||||
Posted in reply to dnoob | 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 Re: chaining splitters | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dave S | 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.
|
Copyright © 1999-2021 by the D Language Foundation