|
using System.Collections.Generic; |
|
using System.Text.RegularExpressions; |
|
|
|
namespace Your.Web.Project |
|
{ |
|
public static class FilterHelper |
|
{ |
|
public static bool HasOption(string query, string option) |
|
{ |
|
var regex = GetRegex(option); |
|
|
|
return regex.IsMatch(query); |
|
} |
|
|
|
public static bool HasOption(string query, params string[] options) |
|
{ |
|
foreach (var option in options) |
|
{ |
|
if (HasOption(query, option)) |
|
{ |
|
return true; |
|
} |
|
} |
|
|
|
return false; |
|
} |
|
|
|
public static bool HasGenericOption(string query, string field) |
|
{ |
|
var regex = GetGenericRegex(field); |
|
|
|
return regex.IsMatch(query); |
|
} |
|
|
|
public static bool HasGenericOption(string query, params string[] fields) |
|
{ |
|
foreach (var field in fields) |
|
{ |
|
if (HasGenericOption(query, field)) |
|
{ |
|
return true; |
|
} |
|
} |
|
|
|
return false; |
|
} |
|
|
|
public static string GetGenericOption(string query, string field) |
|
{ |
|
var value = string.Empty; |
|
|
|
var regex = GetGenericRegex(field); |
|
|
|
var matches = regex.Matches(query); |
|
|
|
foreach (Match match in matches) |
|
{ |
|
var group = match.Groups["value"]; |
|
|
|
if (group.Success) |
|
{ |
|
value = group.Value; |
|
|
|
break; |
|
} |
|
} |
|
|
|
return value.Trim(); |
|
} |
|
|
|
public static string PrependOption(string query, string option) |
|
{ |
|
return Compact(string.Format("{0} {1}", option, query)); |
|
} |
|
|
|
public static string PrependGenericOption(string query, string field, string value) |
|
{ |
|
return PrependOption(query, FormatGenericOption(field, value)); |
|
} |
|
|
|
public static string AppendOption(string query, string option) |
|
{ |
|
return Compact(string.Format("{0} {1}", query, option)); |
|
} |
|
|
|
public static string AppendGenericOption(string query, string field, string value) |
|
{ |
|
return AppendOption(query, FormatGenericOption(field, value)); |
|
} |
|
|
|
public static string RemoveOption(string query, string option) |
|
{ |
|
return Compact(query.Replace(option, " ")); |
|
} |
|
|
|
public static string RemoveOption(string query, params string[] options) |
|
{ |
|
foreach (var option in options) |
|
{ |
|
query = RemoveOption(query, option); |
|
} |
|
|
|
return query; |
|
} |
|
|
|
public static string RemoveGenericOption(string query, string field) |
|
{ |
|
var regex = GetGenericRegex(field); |
|
|
|
return Compact(regex.Replace(query, " ")); |
|
} |
|
|
|
public static string RemoveGenericOption(string query, params string[] fields) |
|
{ |
|
foreach (var field in fields) |
|
{ |
|
query = RemoveGenericOption(query, field); |
|
} |
|
|
|
return query; |
|
} |
|
|
|
public static string TogglePrependOption(string query, string option, params string[] options) |
|
{ |
|
if (HasOption(query, option)) |
|
{ |
|
return RemoveOption(query, option); |
|
} |
|
else |
|
{ |
|
foreach (var _option in options) |
|
{ |
|
query = RemoveOption(query, _option); |
|
} |
|
|
|
return PrependOption(query, option); |
|
} |
|
} |
|
|
|
public static string ToggleAppendOption(string query, string option, params string[] options) |
|
{ |
|
if (HasOption(query, option)) |
|
{ |
|
return RemoveOption(query, option); |
|
} |
|
else |
|
{ |
|
foreach (var _option in options) |
|
{ |
|
query = RemoveOption(query, _option); |
|
} |
|
|
|
return AppendOption(query, option); |
|
} |
|
} |
|
|
|
public static string FormatGenericOption(string field, string value) |
|
{ |
|
if (string.IsNullOrWhiteSpace(value)) |
|
{ |
|
return string.Empty; |
|
} |
|
else if (value.Contains(" ")) |
|
{ |
|
value = value.Trim('"'); |
|
value = string.Format("\"{0}\"", value); |
|
} |
|
|
|
return string.Format("{0}:{1}", field, value); |
|
} |
|
|
|
private static Regex GetRegex(string option, bool escape = true) |
|
{ |
|
Regex regex; |
|
|
|
if (escape) |
|
{ |
|
option = Regex.Escape(option); |
|
} |
|
|
|
if (!compiled.TryGetValue(option, out regex)) |
|
{ |
|
var pattern = string.Format(specificOptionTemplate, option); |
|
|
|
regex = new Regex(pattern, RegexOptions.Compiled | RegexOptions.IgnorePatternWhitespace); |
|
|
|
lock (compiled) |
|
{ |
|
if (!compiled.ContainsKey(option)) |
|
{ |
|
compiled.Add(option, regex); |
|
} |
|
} |
|
} |
|
|
|
return regex; |
|
} |
|
|
|
private static Regex GetGenericRegex(string field) |
|
{ |
|
var option = string.Format(genericOptionTemplate, Regex.Escape(field)); |
|
|
|
var regex = GetRegex(option, escape: false); |
|
|
|
return regex; |
|
} |
|
|
|
private static string Compact(string query) |
|
{ |
|
return compacter.Replace(query, " ").Trim(); |
|
} |
|
|
|
private static readonly Dictionary<string, Regex> compiled = new Dictionary<string, Regex>(); |
|
|
|
private static readonly Regex compacter = new Regex(@" +", RegexOptions.Compiled); |
|
|
|
private static readonly string specificOptionTemplate = @" |
|
(^|\ +) |
|
{0} |
|
(\ +|$)"; |
|
|
|
/// <summary> |
|
/// Note the double curly braces; this string is intended to be used with |
|
/// string.Format so they will be collapsed. This string should cover the following: |
|
/// |
|
/// field:value |
|
/// field:(value) |
|
/// field:(value OR value) |
|
/// field:"value value" |
|
/// field:[range1 TO range2] |
|
/// field:{range1 TO range2} |
|
/// field:{range1 TO range2] |
|
/// field:"{any of the above examples}" |
|
/// </summary> |
|
private static readonly string genericOptionTemplate = @" |
|
{0}: |
|
(?<value> |
|
(?<surround>( |
|
(?<quote> "" )| |
|
(?<escquote> \\"" )| |
|
(?<square> \[ )| |
|
(?<curly> \{{ )| |
|
(?<paren> \( ) |
|
))? |
|
(?<inner> |
|
.*? |
|
) |
|
(?(surround)( |
|
(?(quote) (?<!\\)"" | $ )| |
|
(?(escquote) \\"" | $ )| |
|
(?(square) (\}}|\]) | $ )| |
|
(?(curly) (\}}|\]) | $ )| |
|
(?(paren) \) | $ ) |
|
)) |
|
) |
|
"; |
|
} |
|
} |