std.range pipelike interface, inverting OutputStreams?
ikod via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Sat Aug 13 02:34:47 PDT 2016
On Saturday, 13 August 2016 at 02:15:55 UTC, cy wrote:
> I was trying to use std.regex, and it takes an output stream to
> pump the result to, which is great, but I wanted to perform TWO
> replacements, one with the output of the previous, with data
> that might be a tricky size to cache redundantly.
>
> So, ideally when you do something like regexp replacing, you'd
> have a function like:
> InputRange replaceThingy(InputRange source, someregex,
> somereplacer);
>
> It doesn't do that, unfortunately, so I can't easily chain
> replacements. But couldn't I do a thing like...
>
> InputRange pipe(void delegate(ref OutputRange)) { ? }
>
> and then just...
> auto result = pipe((sink) => replaceAllInto(sink, data,
> firstmatch, firstreplacer));
> auto result2 = pipe((sink) => replaceAllInto(sink, result,
> secondmatch, secondreplacer));
> copy(result2,stdout);
>
> ... or something like that? Has that been done before? Can it
> be done?
>
> I'm pretty sure any algorithm that takes an output stream can
> be transformed into an algorithm that provides an input stream,
> but I'm not sure if I'd be reinventing the wheel here, or if my
> assumptions are seriously off.
>
> Hoping to avoid weird stuff like context switches... eh.
Looks like you can't just because std.regex replace* functions
accept only someString as input.
But you can write something like this (sorry for dirty code):
import std.regex;
import std.stdio;
class ReplacePipe {
private {
Regex!char _re;
string _format;
string _input;
ReplacePipe _next;
}
this(string input, string r, string f) {
_re = regex(r);
_format = f;
_input = input;
}
this(ReplacePipe next, string r, string f) {
_re = regex(r);
_format = f;
_next = next;
}
string go(string i) {
return replaceAll(i, _re, _format);
}
string go() {
if ( _next ) {
auto s = _next.go();
return replaceAll(s, _re, _format);;
}
return go(_input);
}
}
ReplacePipe replacePipe(string data, string r, string c) {
return new ReplacePipe(data, r, c);
}
ReplacePipe replacePipe(ReplacePipe output, string r, string c) {
return new ReplacePipe(output, r, c);
}
void main() {
string input = "1 2, 3 4";
auto a = input.replacePipe(r" ", "+").replacePipe(r"\+",
".").go();
assert(a=="1.2,.3.4");
}
More information about the Digitalmars-d-learn
mailing list