public FilterPattern(string filter) { if (filter == null) { throw new ArgumentNullException(nameof(filter)); } if (filter.IndexOf(UPath.DirectorySeparator) >= 0) { throw new ArgumentException("Filter cannot contain directory parts.", nameof(filter)); } this._exactMatch = null; this._regexMatch = null; // Optimized path, most common cases if (filter == "" || filter == "*" || filter == "*.*") { return; } var appendSpecialCaseForWildcardExt = false; var startIndex = 0; StringBuilder builder = null; try { int nextIndex; while ((nextIndex = filter.IndexOfAny(SpecialChars, startIndex)) >= 0) { if (builder == null) { builder = UPath.GetSharedStringBuilder(); builder.Append("^"); } var lengthToEscape = nextIndex - startIndex; if (lengthToEscape > 0) { var toEscape = Regex.Escape(filter.Substring(startIndex, lengthToEscape)); builder.Append(toEscape); } var c = filter[nextIndex]; // special case for wildcard file extension to allow blank extensions as well if (c == '.' && nextIndex == filter.Length - 2 && filter[nextIndex + 1] == '*') { appendSpecialCaseForWildcardExt = true; break; } var regexPatternPart = c == '.' ? "\\." : c == '*' ? ".*?" : "."; builder.Append(regexPatternPart); startIndex = nextIndex + 1; } if (builder == null) { this._exactMatch = filter; } else { if (appendSpecialCaseForWildcardExt) { builder.Append("(\\.[^.]*)?"); } else { var length = filter.Length - startIndex; if (length > 0) { var toEscape = Regex.Escape(filter.Substring(startIndex, length)); builder.Append(toEscape); } } builder.Append("$"); var regexPattern = builder.ToString(); this._regexMatch = new Regex(regexPattern); } } finally { if (builder != null) { builder.Length = 0; } } }
private SearchPattern(ref UPath path, ref string searchPattern) { path.AssertAbsolute(); if (searchPattern == null) { throw new ArgumentNullException(nameof(searchPattern)); } _exactMatch = null; _regexMatch = null; // Optimized path, most common case if (searchPattern == "*") { return; } if (searchPattern.StartsWith("/")) { throw new ArgumentException($"The search pattern `{searchPattern}` cannot start by an absolute path `/`"); } searchPattern = searchPattern.Replace('\\', '/'); // If the path contains any directory, we need to concatenate the directory part with the input path if (searchPattern.IndexOf('/') > 0) { var pathPattern = new UPath(searchPattern); var directory = pathPattern.GetDirectory(); if (!directory.IsNull && !directory.IsEmpty) { path = path / directory; } searchPattern = pathPattern.GetName(); // If the search pattern is again a plain any, optimized path if (searchPattern == "*") { return; } } var startIndex = 0; int nextIndex; StringBuilder builder = null; try { while ((nextIndex = searchPattern.IndexOfAny(SpecialChars, startIndex)) >= 0) { if (builder == null) { builder = UPath.GetSharedStringBuilder(); builder.Append("^"); } var lengthToEscape = nextIndex - startIndex; if (lengthToEscape > 0) { var toEscape = Regex.Escape(searchPattern.Substring(startIndex, lengthToEscape)); builder.Append(toEscape); } var c = searchPattern[nextIndex]; var regexPatternPart = c == '*' ? "[^/]*" : "[^/]"; builder.Append(regexPatternPart); startIndex = nextIndex + 1; } if (builder == null) { _exactMatch = searchPattern; } else { var length = searchPattern.Length - startIndex; if (length > 0) { var toEscape = Regex.Escape(searchPattern.Substring(startIndex, length)); builder.Append(toEscape); } builder.Append("$"); var regexPattern = builder.ToString(); _regexMatch = new Regex(regexPattern); } } finally { if (builder != null) { builder.Length = 0; } } }
private SearchPattern(ref UPath path, ref string searchPattern) { path.AssertAbsolute(); if (searchPattern == null) { throw new ArgumentNullException(nameof(searchPattern)); } _exactMatch = null; _regexMatch = null; // Optimized path, most common case if (searchPattern == "*") { return; } if (searchPattern.StartsWith("/")) { throw new ArgumentException($"The search pattern `{searchPattern}` cannot start by an absolute path `/`"); } searchPattern = searchPattern.Replace('\\', '/'); // If the path contains any directory, we need to concatenate the directory part with the input path if (searchPattern.IndexOf('/') > 0) { var pathPattern = new UPath(searchPattern); var directory = pathPattern.GetDirectory(); if (!directory.IsNull && !directory.IsEmpty) { path = path / directory; } searchPattern = pathPattern.GetName(); // If the search pattern is again a plain any, optimized path if (searchPattern == "*") { return; } } bool appendSpecialCaseForExt3Chars = false; var startIndex = 0; int nextIndex; StringBuilder builder = null; try { while ((nextIndex = searchPattern.IndexOfAny(SpecialChars, startIndex)) >= 0) { if (builder == null) { builder = UPath.GetSharedStringBuilder(); builder.Append("^"); } var lengthToEscape = nextIndex - startIndex; if (lengthToEscape > 0) { var toEscape = Regex.Escape(searchPattern.Substring(startIndex, lengthToEscape)); builder.Append(toEscape); } var c = searchPattern[nextIndex]; var regexPatternPart = c == '*' ? "[^/]*" : "[^/]"; builder.Append(regexPatternPart); // If the specified extension is exactly three characters long, // the method returns files with extensions that begin with the specified extension. // For example, "*.xls" returns both "book.xls" and "book.xlsx". // 012345 // *.txt if (c == '*' && nextIndex + 5 == searchPattern.Length && searchPattern[nextIndex + 1] == '.' && searchPattern.IndexOf('.', nextIndex + 2) < 0) { appendSpecialCaseForExt3Chars = true; } startIndex = nextIndex + 1; } if (builder == null) { _exactMatch = searchPattern; } else { var length = searchPattern.Length - startIndex; if (length > 0) { var toEscape = Regex.Escape(searchPattern.Substring(startIndex, length)); builder.Append(toEscape); } if (appendSpecialCaseForExt3Chars) { builder.Append("[^/]*"); } builder.Append("$"); var regexPattern = builder.ToString(); _regexMatch = new Regex(regexPattern); } } finally { if (builder != null) { builder.Length = 0; } } }