diff --git a/ClosedXML/Excel/CalcEngine/CalcEngineHelpers.cs b/ClosedXML/Excel/CalcEngine/CalcEngineHelpers.cs index 46e96e1..4c1f2d8 100644 --- a/ClosedXML/Excel/CalcEngine/CalcEngineHelpers.cs +++ b/ClosedXML/Excel/CalcEngine/CalcEngineHelpers.cs @@ -1,5 +1,7 @@ using System; +using System.Collections.Generic; using System.Diagnostics; +using System.Linq; using System.Text.RegularExpressions; namespace ClosedXML.Excel.CalcEngine @@ -25,8 +27,11 @@ // convert criteria to string var cs = criteria as string; - if (!string.IsNullOrEmpty(cs)) + if (cs != null) { + if (cs == "") + return cs.Equals(value); + // if criteria is an expression (e.g. ">20"), use calc engine if (cs[0] == '=' || cs[0] == '<' || cs[0] == '>') { @@ -54,11 +59,26 @@ } // if criteria is a regular expression, use regex - if (cs.IndexOf('*') > -1) + if (cs.IndexOfAny(new[] { '*', '?' }) > -1) { - var pattern = cs.Replace(@"\", @"\\"); - pattern = pattern.Replace(".", @"\"); - pattern = pattern.Replace("*", ".*"); + var patternReplacements = new Dictionary>(); + // key: the literal string to match + // value: a tuple: first item: the search pattern, second item: the replacement + patternReplacements.Add(@"~~", new Tuple(@"~~", "~")); + patternReplacements.Add(@"~*", new Tuple(@"~\*", @"\*")); + patternReplacements.Add(@"~?", new Tuple(@"~\?", @"\?")); + patternReplacements.Add(@"?", new Tuple(@"\?", ".?")); + patternReplacements.Add(@"*", new Tuple(@"\*", ".*")); + + var pattern = Regex.Replace( + cs, + "(" + String.Join( + "|", + patternReplacements.Values.Select(t => t.Item1)) + + ")", + m => patternReplacements[m.Value].Item2); + pattern = $"^{pattern}$"; + return Regex.IsMatch(value.ToString(), pattern, RegexOptions.IgnoreCase); }