On Fri, Apr 20, 2012 at 08:44:06AM +0400, Denis Shelomovskij wrote: > 20.04.2012 8:06, H. S. Teoh написал: > >I'm writing some code that does some very simplistic parsing, and I'm > >just totally geeking out on how awesome D is for writing such code: > > > > import std.conv; > > import std.regex; > > import std.stdio; > > > > struct Data { > > string name; > > string phone; > > int age; > > ... // a whole bunch of other stuff > > } > > > > void main() { > > Data d; > > foreach (line; stdin.byLine()) { > > auto m = match(line, "(\w+)\s+(\w+)"); > > It's better not to create a regex every iteration. Use e.g. > --- > auto regEx = regex(`(\w+)\s+(\w+)`); > --- > before foreach. Of course, you are not claiming this as a > high-performance program, but creating a regex every iteration is > too common mistake to show such code to newbies.
You're right, it was unoptimized code. I ended up using ctRegex for them: enum attrRx = ctRegex!`...`; enum blockRx = ctRegex!`...`; if (auto m = match(line, attrRx)) { ... } else if (auto m = match(line, blockRx)) { ... } The fact that D enums can be arbitrary types is just beyond awesome. [...] > > auto key = m.captures[1]; > > One `.idup` here will be better. (sorry, just like to nitpick) Yeah you're right. I'm refactoring the code right now, and it's much better to write it this way: auto key = m.captures[1].idup; auto value = m.captures[2].idup; dgs.get(key, invalidAttr)(key, value); Looks more concise, too. [...] > A shorter variant: > --- > void delegate(string, string)[string] dgs = [ > "name" : (key, value) { d.name = value; }, > "phone": (key, value) { d.phone = value; }, > "age" : (key, value) { d.age = to!int(value); }, > ... // whole bunch of other stuff to > // parse different attributes > ]; [...] Good idea, I really need to work on my delegate syntax. I must admit I still have to look it up each time, 'cos I just can't remember the right syntax with all its shorthands thereof. T -- Let's not fight disease by killing the patient. -- Sean 'Shaleh' Perry