c# - parsing logic proving very complex -
i have string must parse, setting classes vars correctly it. string badly structured can not change it. have tried parsing dont have way without issue. string set of attributes , params used trigger exe cmd line.
i have laid out in way make easier read know 1 continuous string.
here rules how read line. every 'non -dll' command can expect single key , value pair. dlls lines can have single or multiple key-value pairs after initial dll=,' ie 'dll' element contains 0 or more keyvalue or stand alone value split spaces. eg dll=onemoredll, anditsparam=value anotherparam=value lastparam=value value
input string
time=value1 size=value2 dll=adllname dll=anotherdllname, someparam=paramvalue dll=yetanotherdll, someohterparam=anotherparamvalue astandalonevalue dll=onemoredll, anditsparam=value anotherparam=value lastparam=value
i want able parse string following format, thinking each line in string array.
i have tried splitting spaces , 'dll' regex aint scratch or impossible (im sure not). help!
desired output elements, stored in string array
time=value1 size=value2 dll=adllname dll=anotherdllname, someparam=paramvalue dll=yetanotherdll, someohterparam=anotherparamvalue astandalonevalue dll=onemoredll, anditsparam=value anotherparam=value lastparam=value
the following should work, @ least sample case.
- split string ' '
- split each sub-string '='. if there's no '=', take left side.
we're left structure looks this:
{ left = attribute1, right = value1 }, { left = attribute2, right = value2 }, { left = astandalonevalue }
, etc.
now, need group each item previous 'dll'. i'm using extension method taken this answer that.
essentially, group until condition not met. in our case, want stop grouping when hit 'dll' entry. or, if haven't yet hit 'dll' entry, create new group.
the rest formatting output (which may not needed in case).
var instr = "time=value1 size=value2 dll=adllname dll=anotherdllname, someparam=paramvalue dll=yetanotherdll, someohterparam=anotherparamvalue astandalonevalue dll=onemoredll, anditsparam=value anotherparam=value lastparam=value"; bool isbeforeanydll = true; var result = instr.split(new[] { ' ' }, stringsplitoptions.removeemptyentries) .select(r => { var split = r.split('='); if (split.length == 1) return new { left = split[0], right = (string)null }; var left = split[0]; var right = split[1]; return new { left, right }; }) .groupadjacentby((l, r) => { return r.left == "dll" ? isbeforeanydll = false : !isbeforeanydll; }) .select(g => string.join(" ", g.select(gg => { if (gg.right == null) return gg.left; return string.format("{0}={1}", gg.left, gg.right); }))); //https://stackoverflow.com/a/4682163/563532 public static class linqextensions { public static ienumerable<ienumerable<t>> groupadjacentby<t>( ienumerable<t> source, func<t, t, bool> predicate) { using (var e = source.getenumerator()) { if (e.movenext()) { var list = new list<t> { e.current }; var pred = e.current; while (e.movenext()) { if (predicate(pred, e.current)) { list.add(e.current); } else { yield return list; list = new list<t> { e.current }; } pred = e.current; } yield return list; } } } }
output:
time=value1 size=value2 dll=adllname dll=anotherdllname, someparam=paramvalue dll=yetanotherdll, someohterparam=anotherparamvalue astandalonevalue dll=onemoredll, anditsparam=value anotherparam=value lastparam=value
the data grouped after .groupadjacentby()
, following code formatting output.
Comments
Post a Comment