RegEx Problem
-
I have this string: var Line = "Dev: 0 Model: TOSHIBA MK3265GSX Serial: 20FDF20WS FW: GJ002H STW: 0 MaxLBA: 625142447 FDESUPPORTED: 0 PREBOOT: 0 DRIVETRUSTENABLED: 0 DRIVETRUSTSUPPORTED: 0 w128: 41 FULLFW: GJ002H SERVOFW: SDLSUPPORTED: 1 PLATFORM: 0 SAFE: 1 DSTTIMEOUT: 103 ISBOOTORSYSTEM: 1"; I am trying to use RegEx to extract all Key/Value pairs. So far I have:
private static string getWord(ref string Line, string WordToFind)
{
var retVal = string.Empty;if (Line.Contains(WordToFind))
{
var expression = @"(?:(?'Key'\S+): (?'Value'.*?)) ";
Match match = Regex.Match(Line, expression,RegexOptions.IgnoreCase);if (match.Success) { string key = match.Groups\[1\].ToString(); }
}
return retVal;
}When I pass in "Model:" I get back "Dev". What am I doing wrong here?
If it's not broken, fix it until it is
-
I have this string: var Line = "Dev: 0 Model: TOSHIBA MK3265GSX Serial: 20FDF20WS FW: GJ002H STW: 0 MaxLBA: 625142447 FDESUPPORTED: 0 PREBOOT: 0 DRIVETRUSTENABLED: 0 DRIVETRUSTSUPPORTED: 0 w128: 41 FULLFW: GJ002H SERVOFW: SDLSUPPORTED: 1 PLATFORM: 0 SAFE: 1 DSTTIMEOUT: 103 ISBOOTORSYSTEM: 1"; I am trying to use RegEx to extract all Key/Value pairs. So far I have:
private static string getWord(ref string Line, string WordToFind)
{
var retVal = string.Empty;if (Line.Contains(WordToFind))
{
var expression = @"(?:(?'Key'\S+): (?'Value'.*?)) ";
Match match = Regex.Match(Line, expression,RegexOptions.IgnoreCase);if (match.Success) { string key = match.Groups\[1\].ToString(); }
}
return retVal;
}When I pass in "Model:" I get back "Dev". What am I doing wrong here?
If it's not broken, fix it until it is
Is this C#? I've not seen that method of creating named capture groups. Though, if you are going to name your capture groups, you may as well retrieve them by name rather than by index. Also, you only check if the line contains the string to find. Nowhere in your code do you actually look for that as a key or value. And consider that regular expressions are greedy. Your "Value" capture group will capture everything after the first ": ". Also, according to your regular expression, you can have an empty value ("*" means zero or more). I suspect that is not what you want, but maybe you do. Finally, I'm not really sure how "SERVOFW: SDLSUPPORTED: 1" fits into the key/value scenario. Maybe that's a typo. Based on the assumption that values can have spaces, but keys can't have spaces, this may be a more appropriate regular expression:
(?<KEY>(?!:| ).)+: (?<VALUE>((?!:).)+)(?= (((?!:| ).)+:)|$)
Keep in mind that this will find all matches, so you don't watch to just find the first match as you are doing in your example. You want to loop through them all and compare the key/value against the word you are looking for.
-
Is this C#? I've not seen that method of creating named capture groups. Though, if you are going to name your capture groups, you may as well retrieve them by name rather than by index. Also, you only check if the line contains the string to find. Nowhere in your code do you actually look for that as a key or value. And consider that regular expressions are greedy. Your "Value" capture group will capture everything after the first ": ". Also, according to your regular expression, you can have an empty value ("*" means zero or more). I suspect that is not what you want, but maybe you do. Finally, I'm not really sure how "SERVOFW: SDLSUPPORTED: 1" fits into the key/value scenario. Maybe that's a typo. Based on the assumption that values can have spaces, but keys can't have spaces, this may be a more appropriate regular expression:
(?<KEY>(?!:| ).)+: (?<VALUE>((?!:).)+)(?= (((?!:| ).)+:)|$)
Keep in mind that this will find all matches, so you don't watch to just find the first match as you are doing in your example. You want to loop through them all and compare the key/value against the word you are looking for.
AspDotNetDev wrote:
I'm not really sure how "SERVOFW: SDLSUPPORTED: 1" fits into the key/value scenario
Now that I think about it, "SERVOFW" is probably a key with an empty value. That'd take a bit more time to figure out. I'll leave that as an exercise for the reader. :)
-
Is this C#? I've not seen that method of creating named capture groups. Though, if you are going to name your capture groups, you may as well retrieve them by name rather than by index. Also, you only check if the line contains the string to find. Nowhere in your code do you actually look for that as a key or value. And consider that regular expressions are greedy. Your "Value" capture group will capture everything after the first ": ". Also, according to your regular expression, you can have an empty value ("*" means zero or more). I suspect that is not what you want, but maybe you do. Finally, I'm not really sure how "SERVOFW: SDLSUPPORTED: 1" fits into the key/value scenario. Maybe that's a typo. Based on the assumption that values can have spaces, but keys can't have spaces, this may be a more appropriate regular expression:
(?<KEY>(?!:| ).)+: (?<VALUE>((?!:).)+)(?= (((?!:| ).)+:)|$)
Keep in mind that this will find all matches, so you don't watch to just find the first match as you are doing in your example. You want to loop through them all and compare the key/value against the word you are looking for.
I'm piecing toget code formv various places becuase it all looks like greek to me. I'm fairly frustrated at this point. This shouldn't be this difficult. Anyway, here's my code:
if (Line.Contains(WordToFind))
{
Regex r = new Regex(
"(?:(?'Key'\\S+): (?'Value'.*?))",
RegexOptions.RightToLeft
| RegexOptions.CultureInvariant
| RegexOptions.Compiled
);Match m = r.Match(WordToFind); if (m.Success) { }
}
I get no matches for the word "Model". Also, once I get a match, how do I get the Key/Value data???
If it's not broken, fix it until it is
-
I'm piecing toget code formv various places becuase it all looks like greek to me. I'm fairly frustrated at this point. This shouldn't be this difficult. Anyway, here's my code:
if (Line.Contains(WordToFind))
{
Regex r = new Regex(
"(?:(?'Key'\\S+): (?'Value'.*?))",
RegexOptions.RightToLeft
| RegexOptions.CultureInvariant
| RegexOptions.Compiled
);Match m = r.Match(WordToFind); if (m.Success) { }
}
I get no matches for the word "Model". Also, once I get a match, how do I get the Key/Value data???
If it's not broken, fix it until it is
Why did you edit your response? The code I see in the email notification I was sent for your reply to my message looks more correct than the code I now see. For one, you're going to need a for loop to iterate over the result of Matches (not Match). Match finds a single result, and Matches finds all results. For two,
r.Match(WordToFind)
is searching "WordToFind" rather than "Line".Kevin Marois wrote:
once I get a match, how do I get the Key/Value data
You can get groups based on the name. Something like this (I don't have my compiler open, so it may vary slightly):
String key = m.Groups["Key"].Value;
String value = m.Groups["Value"].Value;Kevin Marois wrote:
RegexOptions.RightToLeft
This may drastically change the functionality, but I'm not exactly sure what it does, so you may want to Google this.
Kevin Marois wrote:
I'm fairly frustrated at this point. This shouldn't be this difficult.
Regular expressions are complicated, but powerful. You'll get used to them over time. From what others say, Expresso is a good tool to learn regular expressions, though I use a custom tool I built for myself.