Last active
April 20, 2018 03:50
-
-
Save denisivan0v/90c759ba6fd9192694c1564461c768a0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
namespace FilenameMatch | |
{ | |
internal class Program | |
{ | |
private static int _testCount = 0; | |
private static void Main(string[] args) | |
{ | |
RunTests( | |
("abc", "abc", true), | |
("abc", "a", false), | |
("abc", "ab", false), | |
("a", "ab", false), | |
("", "", true), | |
("", "a", false), | |
("a", "", false), | |
("?", "", true), | |
("*", "", true), | |
("*a", "", false), | |
("?a", "", false), | |
("a*", "", false), | |
("a?", "", false), | |
("**", "", true), | |
("??", "", true), | |
("*?", "", true), | |
("?*", "", true), | |
("*", "abcdef", true), | |
("**", "abcdef", true), | |
("*?", "abcdef", true), | |
("?*", "abcdef", true), | |
("?*?", "abcdef", true), | |
("*?*", "abcdef", true), | |
("a?c", "abc", true), | |
("a?c", "ac", true), | |
("a?c", "abbc", false), | |
("a?c", "bc", false), | |
("a?c", "bbc", false), | |
("?a", "a", true), | |
("?a", "ba", true), | |
("?a", "cba", false), | |
("a?", "a", true), | |
("a?", "ab", true), | |
("a?", "abc", false), | |
("a*c", "abc", true), | |
("a*c", "aac", true), | |
("a*c", "ac", true), | |
("a*c", "abbbbbbbbbbbbbbbbbc", true), | |
("a*c", "abbbbbbbbbbbbbbbbbb", false), | |
("a*c", "bbbbbbbbbbbbbbbbbbc", false), | |
("a*c", "ab", false), | |
("a*c", "bc", false), | |
("?a?b?c?d?e?", "abcde", true), | |
("?a?b?c?d?e?", "aabbccddee", true), | |
("?a?b?c?d?e?", "aaabbbcccdddeee", false), | |
("*a*b*c*d*e*", "abcde", true), | |
("*a*b*c*d*e*", "aabbccddee", true), | |
("*a*b*c*d*e*", "aaabbbcccdddeee", true), | |
("?a*b*c*d*e", "aaabbbcccdddeee", true), | |
("?a*b*c*d*e", "aaabbbcccdddeee", true), | |
("?a*b*c*d*e?", "aaabbbcccdddeee", true), | |
("?a*b*c*d*e?", "1aaabbbcccdddeee2", true), | |
("*a?b?c*d*e?", "aabbcccdddeee", true), | |
("*a?b?c*d*e?", "aaab1bcccdddeee", false), | |
("*a*b?c*d?e?", "aaabbbcccddee", true), | |
("*a*b?c*d?e?", "aaabbcccddeeee", false), | |
("*a*b?c*d?e?", "11aaabbcccdde2", true), | |
("*a*b?c*d?e*", "aaabbcccddeee", true), | |
("*a*b?c*d?e???", "aaabbcccddeee", true), | |
("*.exe", "abcde.exe", true), | |
("*.exe", "abcde.cmd", false), | |
("*.ex?", "abcde.exx", true), | |
("*.ex?", "abcde.ex", true), | |
("fa*ed?fs*dfa?*ajgf.exe", "faedfsdfaajgf.exe", true), | |
("fa*ed?fs*dfa?*ajgf.exe", "faedfsdfaajgf.cmd", false), | |
("fa*ed?fs*dfa?*ajgf.?xe*", "faedfsdfaajgf.xe", true), | |
("fa*ed?fs*dfa?*ajgf.?xe*", "fa11ed2fs3dfa456ajgf.exe", true), | |
("fa*ed?fs*dfa?*ajgf.?xe*", "fa11ed2fs3dfa456ajgf.xe", true), | |
("fa*ed?fs*dfa?*ajgf.?xe*", "fa11ed2fs3dfa456ajgf.xe12345", true), | |
("fa*ed?fs*dfa?*ajgf.?xe*", "fa11ed2fs3dfa456ajgf.exe12345", true), | |
("fa*ed?fs*dfa?*ajgf.?xe*", "fa11ed2fs3dfa456ajgf.1exe12345", false)); | |
} | |
private static void RunTests(params (string pattern, string filename, bool expected)[] values) | |
{ | |
foreach (var value in values) | |
{ | |
var result = Matches(value.pattern, value.filename); | |
Console.Write($"Test #{++_testCount:00}: trying to match '{value.filename}' with '{value.pattern}' -> {result}"); | |
if (value.expected != result) | |
{ | |
var color = Console.ForegroundColor; | |
Console.ForegroundColor = ConsoleColor.Red; | |
Console.Write(" FAIL!"); | |
Console.ForegroundColor = color; | |
} | |
Console.Write(Environment.NewLine); | |
} | |
} | |
private static bool Matches(string pattern, string filename) | |
{ | |
// pattern is empty | |
if (pattern.Length == 0 && filename.Length > 0) | |
{ | |
return false; | |
} | |
for (var index = 0; index < pattern.Length; index++) | |
{ | |
var patternCharacter = pattern[index]; | |
// regular symbols | |
if (patternCharacter != '?' && patternCharacter != '*') | |
{ | |
// filename is empty, pattern is not empty | |
if (filename.Length == 0) | |
{ | |
return false; | |
} | |
// end of pattern, but not end of filename | |
if (index == pattern.Length - 1 && index != filename.Length - 1) | |
{ | |
return false; | |
} | |
// characters doesn't match | |
if (index < filename.Length && patternCharacter != filename[index]) | |
{ | |
return false; | |
} | |
} | |
var nextCharacterIndex = index + 1; | |
if (patternCharacter == '?') | |
{ | |
// end of filename | |
if (filename.Length == 0) | |
{ | |
for (var i = nextCharacterIndex; i < pattern.Length; i++) | |
{ | |
return Matches(pattern.Substring(i), filename); | |
} | |
} | |
// matching 0 or 1 character | |
if (index < filename.Length) | |
{ | |
return Matches(pattern.Substring(nextCharacterIndex), filename.Substring(index)) || | |
Matches(pattern.Substring(nextCharacterIndex), filename.Substring(nextCharacterIndex)); | |
} | |
} | |
if (patternCharacter == '*') | |
{ | |
// last symbol in pattern | |
if (index == pattern.Length - 1) | |
{ | |
return true; | |
} | |
// end of filename | |
if (filename.Length == 0) | |
{ | |
for (var i = nextCharacterIndex; i < pattern.Length; i++) | |
{ | |
return Matches(pattern.Substring(i), filename); | |
} | |
} | |
// keep matching | |
var match = false; | |
for (var i = index; i < filename.Length; i++) | |
{ | |
match = match || Matches(pattern.Substring(nextCharacterIndex), filename.Substring(i)); | |
} | |
return match; | |
} | |
} | |
// both pattern and filename are empty | |
return true; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment