Lean  $LEAN_TAG$
Validate.cs
1 /*
2  * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
3  * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14 */
15 
16 using System;
17 using System.Globalization;
18 using System.Text.RegularExpressions;
19 
20 namespace QuantConnect.Util
21 {
22  /// <summary>
23  /// Provides methods for validating strings following a certain format, such as an email address
24  /// </summary>
25  public static class Validate
26  {
27  /// <summary>
28  /// Validates the provided email address
29  /// </summary>
30  /// <remarks>
31  /// Implementation taken from msdn (with slight refactoring for readability and C#6 compliance):
32  /// https://docs.microsoft.com/en-us/dotnet/standard/base-types/how-to-verify-that-strings-are-in-valid-email-format
33  /// </remarks>
34  /// <param name="emailAddress">The email address to be validated</param>
35  /// <returns>True if the provided email address is valid</returns>
36  public static bool EmailAddress(string emailAddress)
37  {
38  if (string.IsNullOrWhiteSpace(emailAddress))
39  {
40  return false;
41  }
42 
43  emailAddress = NormalizeEmailAddressDomainName(emailAddress);
44  if (emailAddress == null)
45  {
46  // an error occurred during domain name normalization
47  return false;
48  }
49 
50  try
51  {
52  return RegularExpression.Email.IsMatch(emailAddress);
53  }
54  catch
55  {
56  return false;
57  }
58  }
59 
60  private static string NormalizeEmailAddressDomainName(string emailAddress)
61  {
62  try
63  {
64  // Normalize the domain
65  emailAddress = RegularExpression.EmailDomainName.Replace(emailAddress, match =>
66  {
67  // Use IdnMapping class to convert Unicode domain names.
68  var idn = new IdnMapping();
69 
70  // Pull out and process domain name (throws ArgumentException on invalid)
71  var domainName = idn.GetAscii(match.Groups[2].Value);
72 
73  return match.Groups[1].Value + domainName;
74  });
75  }
76  catch
77  {
78  return null;
79  }
80 
81  return emailAddress;
82  }
83 
84  /// <summary>
85  /// Provides static storage of compiled regular expressions to preclude parsing on each invocation
86  /// </summary>
87  public static class RegularExpression
88  {
89  private static readonly TimeSpan MatchTimeout = TimeSpan.FromMilliseconds(100);
90 
91  /// <summary>
92  /// Matches the domain name in an email address ignored@[domain.com]
93  /// Pattern sourced via msdn:
94  /// https://docs.microsoft.com/en-us/dotnet/standard/base-types/how-to-verify-that-strings-are-in-valid-email-format
95  /// </summary>
96  public static readonly Regex EmailDomainName = new Regex(@"(@)(.+)$", RegexOptions.Compiled, MatchTimeout);
97 
98  /// <summary>
99  /// Matches a valid email address address@sub.domain.com
100  /// Pattern sourced via msdn:
101  /// https://docs.microsoft.com/en-us/dotnet/standard/base-types/how-to-verify-that-strings-are-in-valid-email-format
102  /// </summary>
103  public static readonly Regex Email = new Regex(@"^(?("")("".+?(?<!\\)""@)|(([0-9a-z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-z])@))(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-0-9a-z]*[0-9a-z]*\.)+[a-z0-9][\-a-z0-9]{0,22}[a-z0-9]))$", RegexOptions.IgnoreCase | RegexOptions.Compiled, MatchTimeout);
104  }
105  }
106 }