Regex returns values from form result
The result of the web form is sent to me via a text email and I need to parse all the values from it. I would like to have one regex that can return me the result for a given key.
String Pattern = String.Format("^.*{0}:\s*(?<mail><mailto\:)?(.*)(?(mail)>)\s*$", InputString);
I have these 2 options: RegexOptions.IgnoreCase | RegexOptions.Multiline
Here is the piece of text that needs to be analyzed.
City: Test City
Country: Mycountry
Phone: 212
Fax:
E-Mail: <mailto:mymail@example.com>
This works well, except when there is no value, for example. Fax
... If I put Fax
as an InputString, the next next line is returned E-Mail: <mailto:mymail@example.com>
. I want to have either no result or empty.
source to share
Your problem is that even if you are not using RegexOptions.SingleLine
and therefore .
not matching \n
, the character class is \s
matching \n
.
You can fix this by replacing each instance \s
with [^\S\r\n]
, that is, instead of matching "spaces (including newlines)", there is no match (non-whitespace or newline).
string pattern = String.Format(
@"^[^\S\r\n]*{0}:[^\S\r\n]*(?<mail><mailto\:)?(.*)(?(mail)>)[^\S\r\n]*$",
"Fax");
However, you are left with another problem: RegexOptions.Multiline
means ^
or $
matches a \n
, so you are left with the trailing one \r
in your match if the newlines are in your match \r\n
.
To get around this, you cannot use RegexOptions.Multiline
, but instead replace ^
with (?<=^|\r\n)
and $
with (?=$|\r\n)
, which manually matches the newline \r\n
.
source to share
Here is the template and code that puts the items into a dictionary for retrieval. If the value is empty, its key is valid in the dictionary, but the value contained or returned for that key is null.
string data = @"City: Test City
Country: Mycountry
Phone: 212
Fax:
E-Mail: <mailto:mymail@example.com>";
string pattern = @"^(?<Key>[^:]+)(?::)(?<Value>.*)";
var resultDictionary =
Regex.Matches(data, pattern, RegexOptions.Multiline)
.OfType<Match>()
.ToDictionary (mt => mt.Groups["Key"].Value, mt => mt.Groups["Value"].Value);
/* resultDictionary is a dictionary with these values:
City Test City
Country Mycountry
Phone 212
Fax
E-Mail <mailto:mymail@example.com>
*/
source to share