Repository: PowerShell/PowerShell
File: src/System.Management.Automation/engine/regex.cs (C#)

Code before:
        /// <summary>
        /// Converts the wildcard pattern to its regular expression equivalent.
        /// </summary>
        /// <returns>
        /// A string that represents the regular expression equivalent of the wildcard pattern.
        /// </returns>
        /// <remarks>
        /// This method converts a wildcard pattern to a regular expression pattern.
        /// The conversion follows these rules:
        /// <list type="bullet">
        /// <item><description>* (asterisk) converts to .* (matches any string)</description></item>
        /// <item><description>? (question mark) converts to . (matches any single character)</description></item>
        /// <item><description>[abc] (bracket expression) converts to [abc] (matches any character in the set)</description></item>
        /// <item><description>Literal characters are escaped as needed for regex</description></item>
        /// </list>
        /// </remarks>
        /// <example>
        /// <code>
        /// var pattern = new WildcardPattern("*.txt");
        /// string regex = pattern.ToRegex();
        /// // Returns: "\.txt$"
        /// </code>
        /// </example>
        public string ToRegex()
        {
            return PatternConvertedToRegex;
        }

        /// <summary>
        /// Escape special chars, except for those specified in <paramref name="charsNotToEscape"/>, in a string by replacing them with their escape codes.
        /// </summary>
        /// <param name="pattern">The input string containing the text to convert.</param>
        /// <param name="charsNotToEscape">Array of characters that not to escape.</param>
        /// <returns>
        /// A string of characters with any metacharacters, except for those specified in <paramref name="charsNotToEscape"/>, converted to their escaped form.
        /// </returns>
        internal static string Escape(string pattern, char[] charsNotToEscape)
        {
            if (pattern == null)
            {
                throw PSTraceSource.NewArgumentNullException(nameof(pattern));
            }

            if (charsNotToEscape == null)
            {
                throw PSTraceSource.NewArgumentNullException(nameof(charsNotToEscape));
            }

            if (pattern == string.Empty)
            {
                return pattern;

Review comment (suggestion):
I'd somewhat expect a method called `ToRegex()` to return a `Regex`, not a string. Is there a good set of flags to set on `Regex` to reliably match what the pattern does? If so, I think it would be cleaner to return a pre-configured `Regex` instance so that the user is guaranteed to get exactly the same behavior.

Code after:
        /// <item><description>? (question mark) converts to . (matches any single character)</description></item>
        /// <item><description>[abc] (bracket expression) converts to [abc] (matches any character in the set)</description></item>
        /// <item><description>Literal characters are escaped as needed for regex</description></item>
        /// </list>
        /// </remarks>
        /// <example>
        /// <code>
        /// var pattern = new WildcardPattern("*.txt");
        /// Regex regex = pattern.ToRegex();
        /// // regex.ToString() returns: "\.txt$"
        /// </code>
        /// </example>
        public Regex ToRegex()
        {
            return WildcardPatternToRegexParser.Parse(this);
        }

        /// <summary>
        /// Escape special chars, except for those specified in <paramref name="charsNotToEscape"/>, in a string by replacing them with their escape codes.
        /// </summary>
        /// <param name="pattern">The input string containing the text to convert.</param>
        /// <param name="charsNotToEscape">Array of characters that not to escape.</param>
        /// <returns>
        /// A string of characters with any metacharacters, except for those specified in <paramref name="charsNotToEscape"/>, converted to their escaped form.
        /// </returns>
        internal static string Escape(string pattern, char[] charsNotToEscape)
        {
            if (pattern == null)
            {
                throw PSTraceSource.NewArgumentNullException(nameof(pattern));
            }

            if (charsNotToEscape == null)
            {
                throw PSTraceSource.NewArgumentNullException(nameof(charsNotToEscape));
            }

            if (pattern == string.Empty)
            {
                return pattern;
            }

            Span<char> temp = pattern.Length < StackAllocThreshold ? stackalloc char[pattern.Length * 2 + 1] : new char[pattern.Length * 2 + 1];
            int tempIndex = 0;

            for (int i = 0; i < pattern.Length; i++)
            {
                char ch = pattern[i];

                //
                // if it is a special char, escape it