Skip to content

Commit c31d9cf

Browse files
committed
Added String IsLike extension method for comparing string against a wildcard pattern
1 parent 74d40dd commit c31d9cf

2 files changed

Lines changed: 61 additions & 2 deletions

File tree

src/MADE.Data.Validation/Extensions/StringExtensions.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ namespace MADE.Data.Validation.Extensions
55
{
66
using System;
77
using System.Globalization;
8+
using System.Text.RegularExpressions;
89

910
/// <summary>
1011
/// Defines a collection of extensions for string values.
@@ -43,6 +44,43 @@ public static bool Contains(this string phrase, string value, CompareOptions com
4344
return CultureInfo.CurrentCulture.CompareInfo.IndexOf(phrase, value, compareOption) >= 0;
4445
}
4546

47+
/// <summary>
48+
/// Compares a string value against a wildcard pattern, similar to the Visual Basic like operator.
49+
/// </summary>
50+
/// <remarks>
51+
/// An example of this in use comparing strings with * wildcard pattern.
52+
/// <code>
53+
/// // result is true
54+
/// bool result = "MyValue".IsLike("My*");
55+
///
56+
/// // result is false
57+
/// result = "MyValue".IsLike("Hello");
58+
/// </code>
59+
/// </remarks>
60+
/// <param name="value">The value to compare is like.</param>
61+
/// <param name="likePattern">The wildcard like pattern to match on.</param>
62+
/// <returns>True if the value is like the pattern; otherwise, false.</returns>
63+
public static bool IsLike(this string value, string likePattern)
64+
{
65+
if (value.IsNullOrWhiteSpace() || likePattern.IsNullOrWhiteSpace())
66+
{
67+
return false;
68+
}
69+
70+
// Escape any special characters in pattern
71+
var regex = "^" + Regex.Escape(likePattern) + "$";
72+
73+
// Replace wildcard characters with regular expression equivalents
74+
regex = regex.Replace(@"\[!", "[^")
75+
.Replace(@"\[", "[")
76+
.Replace(@"\]", "]")
77+
.Replace(@"\?", ".")
78+
.Replace(@"\*", ".*")
79+
.Replace(@"\#", @"\d");
80+
81+
return Regex.IsMatch(value, regex);
82+
}
83+
4684
/// <summary>
4785
/// Checks whether a string value is an integer.
4886
/// </summary>

tests/MADE.Data.Validation.Tests/Tests/StringExtensionsTests.cs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,35 @@ namespace MADE.Data.Validation.Tests.Tests
22
{
33
using System.Diagnostics.CodeAnalysis;
44
using System.Globalization;
5-
using Extensions;
5+
using MADE.Data.Validation.Extensions;
66
using NUnit.Framework;
77
using Shouldly;
88

99
[ExcludeFromCodeCoverage]
1010
[TestFixture]
1111
public class StringExtensionsTests
1212
{
13+
public class WhenValidatingIfStringIsLike
14+
{
15+
[TestCase("*", "abc", true)]
16+
[TestCase("a*", "abc", true)]
17+
[TestCase("a?c", "abc", true)]
18+
[TestCase("[a-z][a-z][a-z]", "abc", true)]
19+
[TestCase("###", "123", true)]
20+
[TestCase("###", "abc", false)]
21+
[TestCase("*###", "123abc", false)]
22+
[TestCase("[a-z][a-z][a-z]", "ABC", false)]
23+
[TestCase("a?c", "aba", false)]
24+
public void ShouldMatchPattern(string pattern, string input, bool expected)
25+
{
26+
// Act
27+
var actual = input.IsLike(pattern);
28+
29+
// Assert
30+
actual.ShouldBe(expected);
31+
}
32+
}
33+
1334
public class WhenCheckingIfStringContainsValue
1435
{
1536
[TestCase("Hello, World", "ello", CompareOptions.None)]
@@ -141,4 +162,4 @@ public void ShouldReturnFalseIfNotFloat(string value)
141162
}
142163
}
143164
}
144-
}
165+
}

0 commit comments

Comments
 (0)