Created
October 20, 2013 16:29
-
-
Save DmitryOlshansky/7071860 to your computer and use it in GitHub Desktop.
DDoc intro for new std.regex API
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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