Repository: microsoft/ApplicationInspector
File: AppInspector.Common/Utils.cs (C#)

Code before:
﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;

namespace Microsoft.ApplicationInspector.Common;

public static class Utils
{
    /// <summary>
    /// Convert a list of string modifiers specified in a SearchPattern to the appropriate regex modifiers
    /// </summary>
    /// <param name="modifiers"></param>
    /// <returns>A RegexOptions object with the correct modifiers set</returns>
    public static RegexOptions RegexModifierToRegexOptions(IList<string> modifiers, bool enableNonbacktrackingRegex = false)
    {
        RegexOptions opts = new();
        opts |= RegexOptions.Compiled;
#if NET7_0_OR_GREATER
        if (enableNonbacktrackingRegex)
            opts |= RegexOptions.NonBacktracking;
#endif
        foreach (var modifier in modifiers)
        {
            switch (modifier.ToLower())
            {
                case "m":
                case "multiline":
                    opts |= RegexOptions.Multiline;
                    break;
                case "s":
                case "singleline":
                    opts |= RegexOptions.Singleline;
                    break;
                case "i":
                case "ignorecase":
                    opts |= RegexOptions.IgnoreCase;
                    break;
                case "c":
                case "cultureinvariant":
                    opts |= RegexOptions.CultureInvariant;
                    break;
                // This is 'n' to match the options for the Regex api: https://learn.microsoft.com/en-us/dotnet/standard/base-types/regular-expression-options
                case "n":
                case "explicitcapture":
                    opts |= RegexOptions.ExplicitCapture;
                    break;
                case "x":

Review comment (suggestion):
I thinl this switch list is missing two cases now that should be handled. `b` in the case that non backtrack is set and `nb` in either case. The `b` can be set with the `&= ~` technique and the nb with `|=`. Specifically for cases where it's set individually in the rule rather than by parameter. 

Code after:
﻿using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;

namespace Microsoft.ApplicationInspector.Common;

public static class Utils
{
    /// <summary>
    ///     Converts a strings to a compiled regex. Returns null if the Regex cannot be constructed with the given arguments. See <paramref name="logger"/> for details.
    /// </summary>
    /// <param name="built">The regex to build</param>
    /// <param name="regexOptions">The options to use.</param>
    /// <param name="logger">Optional logger to get any exception details details</param>
    /// <returns>The built Regex, or null if a Regex could not be constructed</returns>
    public static Regex? StringToRegex(string built, RegexOptions regexOptions, ILogger? logger)
    {
        try
        {
            return new Regex(built, regexOptions);
        }
#if NET7_0_OR_GREATER
        catch (NotSupportedException)
        {
            // Its possible that this regex is not compatible with the non-backtracking engine
            // Try constructing it without NonBackTracking
            regexOptions &= ~RegexOptions.NonBacktracking;
            try
            {
                Regex backTrackedRegex = new Regex(built, regexOptions);
                logger?.LogDebug("Could not construct the regular expression {pattern} with NonBackTracking so it was constructed without NonBackTracking.", built);
                return backTrackedRegex;
            }
            catch (Exception e)
            {
                logger?.LogWarning("Could not construct the regular expression {pattern} with options {regOpts}. ({exceptionType}: {exceptionMessage})", built, string.Join(",", regexOptions), e.GetType().Name, e.Message);
            }
        }
#endif
        catch (Exception e)
        {
            logger?.LogWarning("Could not construct the regular expression {pattern} with options {regOpts}. ({exceptionType}: {exceptionMessage})", built, string.Join(",", regexOptions), e.GetType().Name, e.Message);
        }

        return null;
    }