I did this with LINQ ... maybe not the best way, but it was interesting to figure out:
string test = "<info:\"Enterprise Optimizer 7.4 for COR Technology 5.5 -- Advanced Solver Edition\", url:\"http://EO.riverlogic.com\", url_menu:\"EO Online...\", app_id:\"EOAS\",app_name:\"Enterprise Optimizer AS\", **app_major:7**, **app_minor:4**,**app_micro:5**,app_copyright:\"251 1996-2010 River Logic Inc.\r\nAll Rights Reserved.\">"; var result = test.Split(','). Select(p => p.Trim().Split(':')). Where(i => i[0].Trim().StartsWith("**app_")). Select(r => new { Key = r[0].Trim('*'), Value = r[1].TrimEnd('*') });
It produces:
result = {{Key = "app_major", Value = "7"}, {Key = "app_minor", Value = "4"}, {Key = "app_micro", Value = "5"}}
Perhaps this could even be made much more elegant :)
EDIT: If you want to make it very easy to access what you want to do:
var result = test.Split(','). Select(p => p.Trim().Split(':')). Where(i => i[0].Trim().StartsWith("**app_")). Select(r => new { Key = r[0].Trim('*'), Value = r[1].TrimEnd('*') }). ToDictionary(k => k.Key, v => v.Value);
Then, to get the value, just give it the key:
var version = result["app_major"] ?? "Not Found";
Note. I tested the LINQ solution and the Regex solution, and the LINQ version is not so different from the speed, but it is a little slower than the published regular expression answers. The regular expression of the response, although it does not clear the data for you, is presented in a simple way. The ToDictionary part really slows it down (from a real-time point of view, although it remains almost nothing), but makes it easier to use.