private string GlobRegexItemToRegex(GlobRegexItem item) { switch (item.ItemType) { case GlobRegexItemType.GlobStar: case GlobRegexItemType.GlobStarForFileOnly: // If globstar is disabled if (!Options.HasFlag(GlobMatcherOptions.AllowGlobStar)) { return(SingleStarToRegex); } if (Options.HasFlag(GlobMatcherOptions.AllowDotMatch)) { // ** when dots are allowed, allows anything except .. and . // not (^ or / followed by one or two dots followed by $ or /) return(@"(?:(?!(?:\/|^)(?:\.{1,2})($|\/)).)*?"); } else { // not (^ or / followed by a dot) return(@"(?:(?!(?:\/|^)\.).)*?"); } case GlobRegexItemType.PlainText: case GlobRegexItemType.Regex: return(item.RegexContent); default: throw new NotSupportedException($"{item.ItemType} is not current supported."); } }
private bool MatchOne(string[] fileParts, GlobRegexItem[] globParts, bool matchPartialGlob) { bool[,] status = new bool[2, globParts.Length + 1]; int prev = 0; int cur = 1; status[0, 0] = true; for (int j = 0; j < globParts.Length; j++) { if (matchPartialGlob) { status[0, j + 1] = true; } else { var globPart = globParts[globParts.Length - j - 1]; if (globPart.ItemType == GlobRegexItemType.GlobStar) status[0, j + 1] = status[0, j]; else status[0, j + 1] = false; } } for(int i = 0; i < fileParts.Length; i++) { status[cur, 0] = false; for (int j = 0; j < globParts.Length; j++) { var filePart = fileParts[fileParts.Length - i - 1]; var globPart = globParts[globParts.Length - j - 1]; switch (globPart.ItemType) { case GlobRegexItemType.GlobStar: if (DisallowedMatchExists(filePart)) status[cur, j + 1] = false; else { var isFolderPath = IsFolderPath(filePart); status[cur, j + 1] = (status[prev, j + 1] && isFolderPath) || (status[prev, j] && isFolderPath || status[cur, j]); } break; case GlobRegexItemType.GlobStarForFileOnly: if (DisallowedMatchExists(filePart)) status[cur, j + 1] = false; else { var isFolderPath = IsFolderPath(filePart); status[cur, j + 1] = status[prev, j + 1] || (status[prev, j] && !isFolderPath); } break; case GlobRegexItemType.PlainText: StringComparison comparison = StringComparison.Ordinal; if (Options.HasFlag(GlobMatcherOptions.IgnoreCase)) { comparison = StringComparison.OrdinalIgnoreCase; } status[cur, j + 1] = string.Equals(filePart, globPart.PlainText, comparison) && status[prev, j]; break; case GlobRegexItemType.Regex: status[cur, j + 1] = globPart.Regex.IsMatch(filePart) && status[prev, j]; break; } } prev ^= 1; cur ^= 1; } return status[prev, globParts.Length]; }
private string GlobRegexItemToRegex(GlobRegexItem item) { switch (item.ItemType) { case GlobRegexItemType.GlobStar: case GlobRegexItemType.GlobStarForFileOnly: // If globstar is disabled if (!Options.HasFlag(GlobMatcherOptions.AllowGlobStar)) { return SingleStarToRegex; } if (Options.HasFlag(GlobMatcherOptions.AllowDotMatch)) { // ** when dots are allowed, allows anything except .. and . // not (^ or / followed by one or two dots followed by $ or /) return @"(?:(?!(?:\/|^)(?:\.{1,2})($|\/)).)*?"; } else { // not (^ or / followed by a dot) return @"(?:(?!(?:\/|^)\.).)*?"; } case GlobRegexItemType.PlainText: case GlobRegexItemType.Regex: return item.RegexContent; default: throw new NotSupportedException($"{item.ItemType} is not current supported."); } }