Skip to content

Don't use compiled Regexes and make sure they are all static #1120

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 17, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 30 additions & 28 deletions RestSharp/Extensions/StringExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ public static string UrlEncode(this string input)
public static string RemoveUnderscoresAndDashes(this string input) =>
input.Replace("_", "").Replace("-", "");

private static readonly Regex DateRegex = new Regex(@"\\?/Date\((-?\d+)(-|\+)?([0-9]{4})?\)\\?/");
private static readonly Regex NewDateRegex = new Regex(@"newDate\((-?\d+)*\)");

/// <summary>
/// Parses most common JSON date formats
/// </summary>
Expand All @@ -103,14 +106,14 @@ public static DateTime ParseJsonDate(this string input, CultureInfo culture)
}

if (input.Contains("/Date("))
return ExtractDate(input, @"\\?/Date\((-?\d+)(-|\+)?([0-9]{4})?\)\\?/", culture);
return ExtractDate(input, DateRegex, culture);

if (input.Contains("new Date("))
{
input = input.Replace(" ", "");

// because all whitespace is removed, match against newDate( instead of new Date(
return ExtractDate(input, @"newDate\((-?\d+)*\)", culture);
return ExtractDate(input, NewDateRegex, culture);
}

return ParseFormattedDate(input, culture);
Expand Down Expand Up @@ -150,10 +153,9 @@ private static DateTime ParseFormattedDate(string input, CultureInfo culture)
return DateTime.TryParse(input, culture, DateTimeStyles.None, out date) ? date : default(DateTime);
}

private static DateTime ExtractDate(string input, string pattern, CultureInfo culture)
private static DateTime ExtractDate(string input, Regex regex, CultureInfo culture)
{
var dt = DateTime.MinValue;
var regex = new Regex(pattern);

if (!regex.IsMatch(input)) return dt;

Expand All @@ -176,14 +178,6 @@ private static DateTime ExtractDate(string input, string pattern, CultureInfo cu
return dt;
}

/// <summary>
/// Checks a string to see if it matches a regex
/// </summary>
/// <param name="input">String to check</param>
/// <param name="pattern">Pattern to match</param>
/// <returns>bool</returns>
public static bool Matches(this string input, string pattern) => Regex.IsMatch(input, pattern);

/// <summary>
/// Converts a string to pascal case
/// </summary>
Expand Down Expand Up @@ -250,39 +244,45 @@ public static string ToCamelCase(this string lowercaseAndUnderscoredWord, Cultur
public static string MakeInitialLowerCase(this string word) =>
string.Concat(word.Substring(0, 1).ToLower(), word.Substring(1));

private static readonly Regex IsUpperCaseRegex = new Regex(@"^[A-Z]+$");

/// <summary>
/// Checks to see if a string is all uppper case
/// </summary>
/// <param name="inputString">String to check</param>
/// <returns>bool</returns>
public static bool IsUpperCase(this string inputString) => Regex.IsMatch(inputString, @"^[A-Z]+$");
public static bool IsUpperCase(this string inputString) => IsUpperCaseRegex.IsMatch(inputString);

private static readonly Regex AddUnderscoresRegex1 = new Regex(@"[-\s]");
private static readonly Regex AddUnderscoresRegex2 = new Regex(@"([a-z\d])([A-Z])");
private static readonly Regex AddUnderscoresRegex3 = new Regex(@"([A-Z]+)([A-Z][a-z])");

/// <summary>
/// Add underscores to a pascal-cased string
/// </summary>
/// <param name="pascalCasedWord">String to convert</param>
/// <returns>string</returns>
public static string AddUnderscores(this string pascalCasedWord) =>
Regex.Replace(
Regex.Replace(
Regex.Replace(pascalCasedWord, @"([A-Z]+)([A-Z][a-z])", "$1_$2"),
@"([a-z\d])([A-Z])",
AddUnderscoresRegex1.Replace(
AddUnderscoresRegex2.Replace(
AddUnderscoresRegex3.Replace(pascalCasedWord, "$1_$2"),
"$1_$2"),
@"[-\s]",
"_");

private static readonly Regex AddDashesRegex1 = new Regex(@"[\s]");
private static readonly Regex AddDashesRegex2 = new Regex(@"([a-z\d])([A-Z])");
private static readonly Regex AddDashesRegex3 = new Regex(@"([A-Z]+)([A-Z][a-z])");

/// <summary>
/// Add dashes to a pascal-cased string
/// </summary>
/// <param name="pascalCasedWord">String to convert</param>
/// <returns>string</returns>
public static string AddDashes(this string pascalCasedWord) =>
Regex.Replace(
Regex.Replace(
Regex.Replace(pascalCasedWord, @"([A-Z]+)([A-Z][a-z])", "$1-$2"),
@"([a-z\d])([A-Z])",
AddDashesRegex1.Replace(
AddDashesRegex2.Replace(
AddDashesRegex3.Replace(pascalCasedWord, "$1-$2"),
"$1-$2"),
@"[\s]",
"-");

/// <summary>
Expand All @@ -292,18 +292,20 @@ public static string AddDashes(this string pascalCasedWord) =>
/// <returns></returns>
public static string AddUnderscorePrefix(this string pascalCasedWord) => string.Format("_{0}", pascalCasedWord);

private static readonly Regex AddSpacesRegex1 = new Regex(@"[-\s]");
private static readonly Regex AddSpacesRegex2 = new Regex(@"([a-z\d])([A-Z])");
private static readonly Regex AddSpacesRegex3 = new Regex(@"([A-Z]+)([A-Z][a-z])");

/// <summary>
/// Add spaces to a pascal-cased string
/// </summary>
/// <param name="pascalCasedWord">String to convert</param>
/// <returns>string</returns>
public static string AddSpaces(this string pascalCasedWord) =>
Regex.Replace(
Regex.Replace(
Regex.Replace(pascalCasedWord, @"([A-Z]+)([A-Z][a-z])", "$1 $2"),
@"([a-z\d])([A-Z])",
AddSpacesRegex1.Replace(
AddSpacesRegex2.Replace(
AddSpacesRegex3.Replace(pascalCasedWord, "$1 $2"),
"$1 $2"),
@"[-\s]",
" ");

/// <summary>
Expand Down
4 changes: 3 additions & 1 deletion RestSharp/Http.cs
Original file line number Diff line number Diff line change
Expand Up @@ -434,9 +434,11 @@ private void ProcessResponseStream(Stream webResponseStream, HttpResponse respon
ResponseWriter(webResponseStream);
}

private static readonly Regex AddRangeRegex = new Regex("(\\w+)=(\\d+)-(\\d+)$");

private static void AddRange(HttpWebRequest r, string range)
{
var m = Regex.Match(range, "(\\w+)=(\\d+)-(\\d+)$");
var m = AddRangeRegex.Match(range);

if (!m.Success)
return;
Expand Down
5 changes: 2 additions & 3 deletions RestSharp/RestClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,9 @@ public partial class RestClient : IRestClient
// silverlight friendly way to get current version
private static readonly Version version = new AssemblyName(Assembly.GetExecutingAssembly().FullName).Version;

private static readonly Regex StructuredSyntaxSuffixRegex = new Regex(@"\+\w+$", RegexOptions.Compiled);
private static readonly Regex StructuredSyntaxSuffixRegex = new Regex(@"\+\w+$");

private static readonly Regex StructuredSyntaxSuffixWildcardRegex =
new Regex(@"^\*\+\w+$", RegexOptions.Compiled);
private static readonly Regex StructuredSyntaxSuffixWildcardRegex = new Regex(@"^\*\+\w+$");

/// <summary>
/// Default constructor that registers default content handlers
Expand Down
6 changes: 3 additions & 3 deletions RestSharp/RestRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,8 @@ public IRestRequest AddOrUpdateParameter(string name, object value, string conte
});
}

private static readonly Regex PortSplitRegex = new Regex(@":\d+");

/// <inheritdoc />
/// <summary>
/// Shortcut to AddParameter(name, value, HttpHeader) overload
Expand All @@ -558,11 +560,9 @@ public IRestRequest AddOrUpdateParameter(string name, object value, string conte
/// <returns></returns>
public IRestRequest AddHeader(string name, string value)
{
const string portSplit = @":\d+";

bool InvalidHost(string host)
{
return Uri.CheckHostName(Regex.Split(host, portSplit)[0]) == UriHostNameType.Unknown;
return Uri.CheckHostName(PortSplitRegex.Split(host)[0]) == UriHostNameType.Unknown;
}

if (name == "Host" && InvalidHost(value))
Expand Down