diff --git a/SabreTools.Filter/FilterObject.cs b/SabreTools.Filter/FilterObject.cs
index 696dfc79..bc611c1f 100644
--- a/SabreTools.Filter/FilterObject.cs
+++ b/SabreTools.Filter/FilterObject.cs
@@ -1,5 +1,4 @@
using System;
-using System.Linq;
using System.Text.RegularExpressions;
using SabreTools.Core.Tools;
using SabreTools.Models.Internal;
@@ -86,57 +85,75 @@ namespace SabreTools.Filter
///
/// Determines if a value matches exactly
///
- ///
- /// TODO: Add regex matching to this method
- ///
private bool MatchesEqual(DictionaryBase dictionaryBase)
{
+ // If the key doesn't exist, we count it as null
if (!dictionaryBase.ContainsKey(this.Key[1]))
return this.Value == null;
+ // If the value in the dictionary is null
string? checkValue = dictionaryBase.ReadString(this.Key[1]);
+ if (checkValue == null)
+ return this.Value == null;
+
+ // If we have both a potentially numeric check and value
if (NumberHelper.IsNumeric(checkValue) && NumberHelper.IsNumeric(this.Value))
{
+ // Check Int64 values
long? checkValueLong = NumberHelper.ConvertToInt64(checkValue);
long? matchValueLong = NumberHelper.ConvertToInt64(checkValue);
if (checkValueLong != null && matchValueLong != null)
return checkValueLong == matchValueLong;
+ // Check Double values
double? checkValueDouble = NumberHelper.ConvertToDouble(checkValue);
double? matchValueDouble = NumberHelper.ConvertToDouble(checkValue);
if (checkValueDouble != null && matchValueDouble != null)
return checkValueDouble == matchValueDouble;
}
- return checkValue == this.Value;
+ // If the value might contain valid Regex
+ if (this.Value != null && ContainsRegex(this.Value))
+ return Regex.IsMatch(checkValue, this.Value);
+
+ return string.Equals(checkValue, this.Value, StringComparison.OrdinalIgnoreCase);
}
///
/// Determines if a value does not match exactly
///
- ///
- /// TODO: Add regex matching to this method
- ///
private bool MatchesNotEqual(DictionaryBase dictionaryBase)
{
+ // If the key doesn't exist, we count it as null
if (!dictionaryBase.ContainsKey(this.Key[1]))
return this.Value != null;
+ // If the value in the dictionary is null
string? checkValue = dictionaryBase.ReadString(this.Key[1]);
+ if (checkValue == null)
+ return this.Value == null;
+
+ // If we have both a potentially numeric check and value
if (NumberHelper.IsNumeric(checkValue) && NumberHelper.IsNumeric(this.Value))
{
+ // Check Int64 values
long? checkValueLong = NumberHelper.ConvertToInt64(checkValue);
long? matchValueLong = NumberHelper.ConvertToInt64(checkValue);
if (checkValueLong != null && matchValueLong != null)
return checkValueLong != matchValueLong;
+ // Check Double values
double? checkValueDouble = NumberHelper.ConvertToDouble(checkValue);
double? matchValueDouble = NumberHelper.ConvertToDouble(checkValue);
if (checkValueDouble != null && matchValueDouble != null)
return checkValueDouble != matchValueDouble;
}
- return checkValue != this.Value;
+ // If the value might contain valid Regex
+ if (this.Value != null && ContainsRegex(this.Value))
+ return !Regex.IsMatch(checkValue, this.Value);
+
+ return !string.Equals(checkValue, this.Value, StringComparison.OrdinalIgnoreCase);
}
///
@@ -144,27 +161,29 @@ namespace SabreTools.Filter
///
private bool MatchesGreaterThan(DictionaryBase dictionaryBase)
{
+ // If the key doesn't exist, we count it as null
if (!dictionaryBase.ContainsKey(this.Key[1]))
return false;
- long? checkLongValue = dictionaryBase.ReadLong(this.Key[1]);
- if (checkLongValue != null)
+ // If the value in the dictionary is null
+ string? checkValue = dictionaryBase.ReadString(this.Key[1]);
+ if (checkValue == null)
+ return false;
+
+ // If we have both a potentially numeric check and value
+ if (NumberHelper.IsNumeric(checkValue) && NumberHelper.IsNumeric(this.Value))
{
- long? matchValue = NumberHelper.ConvertToInt64(this.Value);
- if (matchValue == null)
- return false;
+ // Check Int64 values
+ long? checkValueLong = NumberHelper.ConvertToInt64(checkValue);
+ long? matchValueLong = NumberHelper.ConvertToInt64(checkValue);
+ if (checkValueLong != null && matchValueLong != null)
+ return checkValueLong > matchValueLong;
- return checkLongValue > matchValue;
- }
-
- double? checkDoubleValue = dictionaryBase.ReadDouble(this.Key[1]);
- if (checkDoubleValue != null)
- {
- double? matchValue = NumberHelper.ConvertToDouble(this.Value);
- if (matchValue == null)
- return false;
-
- return checkDoubleValue > matchValue;
+ // Check Double values
+ double? checkValueDouble = NumberHelper.ConvertToDouble(checkValue);
+ double? matchValueDouble = NumberHelper.ConvertToDouble(checkValue);
+ if (checkValueDouble != null && matchValueDouble != null)
+ return checkValueDouble > matchValueDouble;
}
return false;
@@ -175,27 +194,29 @@ namespace SabreTools.Filter
///
private bool MatchesGreaterThanOrEqual(DictionaryBase dictionaryBase)
{
+ // If the key doesn't exist, we count it as null
if (!dictionaryBase.ContainsKey(this.Key[1]))
return false;
- long? checkLongValue = dictionaryBase.ReadLong(this.Key[1]);
- if (checkLongValue != null)
+ // If the value in the dictionary is null
+ string? checkValue = dictionaryBase.ReadString(this.Key[1]);
+ if (checkValue == null)
+ return false;
+
+ // If we have both a potentially numeric check and value
+ if (NumberHelper.IsNumeric(checkValue) && NumberHelper.IsNumeric(this.Value))
{
- long? matchValue = NumberHelper.ConvertToInt64(this.Value);
- if (matchValue == null)
- return false;
+ // Check Int64 values
+ long? checkValueLong = NumberHelper.ConvertToInt64(checkValue);
+ long? matchValueLong = NumberHelper.ConvertToInt64(checkValue);
+ if (checkValueLong != null && matchValueLong != null)
+ return checkValueLong >= matchValueLong;
- return checkLongValue >= matchValue;
- }
-
- double? checkDoubleValue = dictionaryBase.ReadDouble(this.Key[1]);
- if (checkDoubleValue != null)
- {
- double? matchValue = NumberHelper.ConvertToDouble(this.Value);
- if (matchValue == null)
- return false;
-
- return checkDoubleValue >= matchValue;
+ // Check Double values
+ double? checkValueDouble = NumberHelper.ConvertToDouble(checkValue);
+ double? matchValueDouble = NumberHelper.ConvertToDouble(checkValue);
+ if (checkValueDouble != null && matchValueDouble != null)
+ return checkValueDouble >= matchValueDouble;
}
return false;
@@ -206,27 +227,29 @@ namespace SabreTools.Filter
///
private bool MatchesLessThan(DictionaryBase dictionaryBase)
{
+ // If the key doesn't exist, we count it as null
if (!dictionaryBase.ContainsKey(this.Key[1]))
return false;
- long? checkLongValue = dictionaryBase.ReadLong(this.Key[1]);
- if (checkLongValue != null)
+ // If the value in the dictionary is null
+ string? checkValue = dictionaryBase.ReadString(this.Key[1]);
+ if (checkValue == null)
+ return false;
+
+ // If we have both a potentially numeric check and value
+ if (NumberHelper.IsNumeric(checkValue) && NumberHelper.IsNumeric(this.Value))
{
- long? matchValue = NumberHelper.ConvertToInt64(this.Value);
- if (matchValue == null)
- return false;
+ // Check Int64 values
+ long? checkValueLong = NumberHelper.ConvertToInt64(checkValue);
+ long? matchValueLong = NumberHelper.ConvertToInt64(checkValue);
+ if (checkValueLong != null && matchValueLong != null)
+ return checkValueLong < matchValueLong;
- return checkLongValue < matchValue;
- }
-
- double? checkDoubleValue = dictionaryBase.ReadDouble(this.Key[1]);
- if (checkDoubleValue != null)
- {
- double? matchValue = NumberHelper.ConvertToDouble(this.Value);
- if (matchValue == null)
- return false;
-
- return checkDoubleValue < matchValue;
+ // Check Double values
+ double? checkValueDouble = NumberHelper.ConvertToDouble(checkValue);
+ double? matchValueDouble = NumberHelper.ConvertToDouble(checkValue);
+ if (checkValueDouble != null && matchValueDouble != null)
+ return checkValueDouble < matchValueDouble;
}
return false;
@@ -237,27 +260,29 @@ namespace SabreTools.Filter
///
private bool MatchesLessThanOrEqual(DictionaryBase dictionaryBase)
{
+ // If the key doesn't exist, we count it as null
if (!dictionaryBase.ContainsKey(this.Key[1]))
return false;
- long? checkLongValue = dictionaryBase.ReadLong(this.Key[1]);
- if (checkLongValue != null)
+ // If the value in the dictionary is null
+ string? checkValue = dictionaryBase.ReadString(this.Key[1]);
+ if (checkValue == null)
+ return false;
+
+ // If we have both a potentially numeric check and value
+ if (NumberHelper.IsNumeric(checkValue) && NumberHelper.IsNumeric(this.Value))
{
- long? matchValue = NumberHelper.ConvertToInt64(this.Value);
- if (matchValue == null)
- return false;
+ // Check Int64 values
+ long? checkValueLong = NumberHelper.ConvertToInt64(checkValue);
+ long? matchValueLong = NumberHelper.ConvertToInt64(checkValue);
+ if (checkValueLong != null && matchValueLong != null)
+ return checkValueLong <= matchValueLong;
- return checkLongValue <= matchValue;
- }
-
- double? checkDoubleValue = dictionaryBase.ReadDouble(this.Key[1]);
- if (checkDoubleValue != null)
- {
- double? matchValue = NumberHelper.ConvertToDouble(this.Value);
- if (matchValue == null)
- return false;
-
- return checkDoubleValue <= matchValue;
+ // Check Double values
+ double? checkValueDouble = NumberHelper.ConvertToDouble(checkValue);
+ double? matchValueDouble = NumberHelper.ConvertToDouble(checkValue);
+ if (checkValueDouble != null && matchValueDouble != null)
+ return checkValueDouble <= matchValueDouble;
}
return false;
@@ -267,6 +292,43 @@ namespace SabreTools.Filter
#region Helpers
+ ///
+ /// Determine if a value may contain regex for matching
+ ///
+ ///
+ /// If a value contains one of the following characters:
+ /// ^ $ * ? +
+ /// Then it will attempt to check if the value is regex or not.
+ /// If none of those characters exist, then value will assumed
+ /// not to be regex.
+ ///
+ private static bool ContainsRegex(string? value)
+ {
+ // If the value is missing, it can't be regex
+ if (value == null)
+ return false;
+
+ // If we find a special character, try parsing as regex
+ if (value.Contains('^')
+ || value.Contains('$')
+ || value.Contains('*')
+ || value.Contains('?')
+ || value.Contains('+'))
+ {
+ try
+ {
+ _ = new Regex(value);
+ return true;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ return false;
+ }
+
///
/// Derive an operation from the input string, if possible
///