Skip to content

Instantly share code, notes, and snippets.

@DmitryOlshansky
Created October 20, 2013 16:29
Show Gist options
  • Select an option

  • Save DmitryOlshansky/7071860 to your computer and use it in GitHub Desktop.

Select an option

Save DmitryOlshansky/7071860 to your computer and use it in GitHub Desktop.
DDoc intro for new std.regex API
New API for std.regex was introduced. The old API that had its operation mode dependent on "g" (=global) flag was too confusing and error prone. Moreover in some cases it was already being overrided by a function such as by splitter with regex.
New version ties the operation to the function in question, thus being simpler to understand without extra context. Compare 2 samples.
Before:
---
void main()
{
import std.regex, std.algorithm, std.range, std.stdio, std.string;
auto m = "3.141592".match(`(\d+)\.(\d+)`);
//m is a range of ranges
assert(m.front.equal(["3.141592", "3", "141592"]));
//global vs non-global
auto word = regex(`(\w)\w*`);
auto gword = regex(`(\w)\w*`, "g");
auto list = "tomatos, potatos, pineapple";
//this will print only 'tomatos', which raised many WATs
foreach(item; list.match(word))
writeln(item.hit);
//while this will print each of them
foreach(item; list.match(gword))
writeln(item.hit);
auto justFirst = replace!(m => toUpper(m[1]) ~ m[0].drop(1))(list, word);
assert(justFirst == "Tomatos, potatos, pineapple");
auto allOfThem = replace!(m => toUpper(m[1]) ~ m[0].drop(1))(list, gword);
assert(allOfThem == "Tomatos, Potatos, Pineapple");
}
---
After:
---
void main()
{
import std.regex, std.algorithm, std.range, std.stdio, std.string;
auto m = "3.141592".matchFirst(`(\d+)\.(\d+)`);
//m is simply a range of submatches
assert(m.equal(["3.141592", "3", "141592"]));
auto word = regex(`(\w)\w*`);
auto list = "tomatos, potatos, pineapple";
//iterates over submatches so it will print 2 lines:
//tomatos
//t
foreach(item; list.matchFirst(word))
writeln(item);
//so just to get the whole match:
assert(list.matchFirst(word).hit == "tomatos");
//now there is no need to check if it has "g" option
//it's crystal clear in the function name
foreach(item; list.matchAll(word))
writeln(item.hit);
auto justFirst = replaceFirst!(m => toUpper(m[1]) ~ m[0].drop(1))(list, word);
assert(justFirst == "Tomatos, potatos, pineapple");
auto allOfThem = replaceAll!(m => toUpper(m[1]) ~ m[0].drop(1))(list, word);
assert(allOfThem == "Tomatos, Potatos, Pineapple");
//NEW feature - if there is no need to allocate the resulting string
//replacement may be just sent directly to the wire (an OutputRange)
auto sink = stdout.lockingTextWriter();
replaceAllInto!(m => toUpper(m[1]) ~ m[0].drop(1))(sink, list, word);
}
---
Note the new functionality in form of *Into functions that forward the replacement directly to an output range.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment