/// <summary> /// Build regex pattern that captures same parts from filename string. /// /// For example "localization{-Culture}.ini" translates to regex "localization(-(?<Culture>.*))?.ini". /// This can be matched against filename "localization-en.ini" with group m.Group["Culture"].Value == "en". /// </summary> /// <paramref name="pattern"/> /// <paramref name="filledParameters"/>> /// <returns>regex</returns> public static string BuildRegexString(this ILinePattern pattern, IReadOnlyDictionary <string, string> filledParameters, BuildRegexFlags flags = BuildRegexFlags.All) { StringBuilder sb = new StringBuilder(); sb.Append('^'); for (int i = 0; i < pattern.AllParts.Length; i++) { ILinePatternPart part = pattern.AllParts[i]; // Add regular part if (part.Text != null) { sb.Append(Escape(part.Text, flags, BuildRegexFlags.Escape_NonPart)); continue; } string prefilled_value; if (filledParameters != null && filledParameters.TryGetValue(part.Identifier, out prefilled_value) && prefilled_value != null) { if (part.PrefixSeparator != null) { sb.Append(Escape(part.PrefixSeparator, flags, BuildRegexFlags.Escape_Prefix)); } sb.Append(Escape(prefilled_value, flags, BuildRegexFlags.Escape_Identifier)); if (part.PostfixSeparator != null) { sb.Append(Escape(part.PostfixSeparator, flags, BuildRegexFlags.Escape_Postfix)); } } else { sb.Append("("); if (part.PrefixSeparator != null) { sb.Append(Escape(part.PrefixSeparator, flags, BuildRegexFlags.Escape_Prefix)); } sb.Append("(?<"); sb.Append(Escape(part.Identifier, flags, BuildRegexFlags.Escape_Identifier)); sb.Append('>'); // Append type specific pattern Regex part_pattern = part.Regex; string pattern_text = part_pattern.ToString(); int start = 0, end = pattern_text.Length; if (pattern_text.Length > 0 && pattern_text[start] == '^') { start++; } if (pattern_text.Length > 0 && pattern_text[end - 1] == '$') { end--; } if (start < end) { sb.Append(pattern_text.Substring(start, end - start)); } sb.Append(')'); if (part.PostfixSeparator != null) { sb.Append(Escape(part.PostfixSeparator, flags, BuildRegexFlags.Escape_Postfix)); } sb.Append(")"); if (!part.Required) { sb.Append('?'); } } } sb.Append('$'); return(sb.ToString()); }
internal static string Escape(string txt, BuildRegexFlags flags, BuildRegexFlags requiredFlag) => (flags & requiredFlag) != 0 ? Regex.Escape(txt) : txt;