I have the following regex:
var regex = @"\[(\w+)( (\w+)=""([^""]+)"")*\]";
This regex matches strings like:
[Name Parameter="Value" Parameter2="vv"]
[A B="3"]
So, first of all, I want to extend it so it'll match strings, when, if the value is one word, so you don't need a quotation mark before/after the value. For example:
[Name Parameter=OneWord]
I tried:
var regex = @"\[(\w+)( (\w+)=([^""]+))*\]";
but it's not working, so this is my first problem.
My second problem is, that I want t开发者_如何学Goo extend it so it'll match also if there are one or more whitespaces, comma, or comma and one or more whitespaces, but I have no idea how to do this.
Example:
[Name Parameter="SomeWord", p="v" a=b,c=4 P1="2"]
Any ideas?
Thanks.
Don't be afraid to use plenty of whitespace and comments to make the regular expression very readable.
I went ahead and wrote a very simple parser that will read in a string and parse the parameters to a dictionary for easy lookup.
Here's the full sample:
string inputSample = "[Name Parameter=\"SomeWord\", p=\"hello world\" a=b,c=4 P1=\"2\"]";
var m = Regex.Match(inputSample, @"\[
\s*(?<name>\w+) # capture the name
(?<parameter> # start the parameters
[\s,]* # allow whitespace before a parameter
(?<paramName>\w+) # capture the parameter name
\s* # allow whitespace after a name
=
\s* # allow whitespace before a value
( # a value can either be:
(?<paramValue>\w+) # one whole word
| # or
(""(?<paramValue>[^""]*)"") # a quoted string
)
)*
\]", RegexOptions.IgnorePatternWhitespace);
if(m.Success)
{
string name = m.Groups["name"].Value;
Dictionary<string, string> parameters = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
int count = m.Groups["parameter"].Captures.Count;
for(int i = 0; i < count; i++)
{
parameters[m.Groups["paramName"].Captures[i].Value] = m.Groups["paramValue"].Captures[i].Value;
}
string pValue = parameters["p"];
}
This will do it:
\[(\w+)([ \t]+(\w+)=(("([^""]+)")|([A-Za-z][A-Za-z0-9]*)))([, \t]+(\w+)=(("([^""]+)")|([A-Za-z][A-Za-z0-9]*)))*\]
This is how your regex should look like to meet your criteria:
@"\[(\w+)\s*((\s*(\w+)\s*=\s*((""([^""]+)"")|(\w+))\s*),*)*\]"
Edit: New version to include , (comma) matching ...
@"\[(\w+)((?:(?:\s+|,\s*)(?:\w+)\s*=\s*(?:""[^""]*""|[^""]+))*)]
will match your examples and also allow for spaces inside quoted strings. However, it will capture all the parameters as one large string. It's not possible in regex to capture each parameter/value pairs in their own capturing group, so a parser really might be a better idea.
@"\[(\w+)(\s+(\w+)=(""([^""]+)""|\w+))*\]";
精彩评论