C# で ワイルドカードを実装してみます。
ワイルドカードは、「?」が任意の1文字にマッチし、「*」が任意の文字列(0文字以上)にマッチする仕様とします。
WildCardクラス
IsMatch メソッドで入力文字列と、ワイルドカードを含む文字列を渡し、マッチするか判定します。
内部実装としては、ConvertToRegexで正規表現に置換します。具体的には ? を . に、 * を .* に変換しています。
public class WildCard
{
public bool IsMatch(string input, string wildCard)
{
var pattern = ConvertToRegex(wildCard);
return Regex.IsMatch(input, pattern);
}
private string ConvertToRegex(string input)
{
string pattern = string.Empty;
foreach (char c in input)
{
pattern += c switch
{
'?' => ".",
'*' => ".*",
_ => Regex.Escape(c.ToString()),
};
}
return pattern;
}
}
テストクラス
xUnitによるテストコードとしていくつかマッチするパターンと、マッチしないパターンを用意します。
「?」が任意の1文字、「*」が任意の文字列(0文字以上)にマッチするか確認します。
public class WildCardTests
{
[Theory]
[InlineData("abc", "abc", true)]
[InlineData("a?c", "abc", true)]
[InlineData("a?c", "a123c", false)]
[InlineData("a?c", "ac", false)]
[InlineData("a*c", "a123456c", true)]
[InlineData("a*c", "ac", true)]
[InlineData("a*c", "def", false)]
[InlineData("*abc", "123456abc", true)]
[InlineData("log?.txt", "log1.txt", true)]
public void WildCard_ShouldMatchCorrectly(string pattern, string input, bool expected)
{
// Arrange
var wild = new WildCard();
// Act
var actual = wild.IsMatch(input, pattern);
// Assert
Assert.Equal(expected, actual);
}
}
備考
ワイルドカードの仕様としては ~ (チルダ) もあるみたいです。
使ったことがないですね。