function generateOptions(propName, keys, config, isNegative = false) {
  const opacitySuffixes = generateOptionalOpacitySuffix(config);
  const genericArbitraryOption = '\\[(.*)\\]';
  const defaultKeyIndex = keys.findIndex((v) => v === 'DEFAULT');
  if (defaultKeyIndex > -1) {
    keys.splice(defaultKeyIndex, 1);
  }
  const escapedKeys = keys.map((k) => escapeSpecialChars(k));
  switch (propName) {
    case 'dark':
      // Optional `dark` class
      if (config.darkMode === 'class') {
        return 'dark';
      } else if (Array.isArray(config.darkMode) && config.darkMode.length === 2 && config.darkMode[0] === 'class') {
        // https://tailwindcss.com/docs/dark-mode#customizing-the-class-name
        // For the sake of simplicity we only support a single class name
        let value = '';
        const res = /^\.(?<classnameValue>[A-Z0-9\:\-\_\[\d\]]*)$/gi.exec(config.darkMode[1]);
        if (res && res.groups) {
          if (res.groups.classnameValue) {
            value = res.groups.classnameValue;
          }
        }
        return value;
      } else {
        return '';
      }
    case 'arbitraryProperties':
      escapedKeys.push(genericArbitraryOption);
      return '(' + escapedKeys.join('|') + ')';
    case 'colors':
    case 'accentColor':
    case 'borderColor':
    case 'boxShadowColor':
    case 'divideColor':
    case 'fill':
    case 'outlineColor':
    case 'textColor':
    case 'stroke':
    case 'gradientColorStopPositions':
      // Colors can use segments like 'indigo' and 'indigo-light'
      // https://tailwindcss.com/docs/customizing-colors#color-object-syntax
      const options = [];
      keys.forEach((k) => {
        const color = config.theme[propName][k] || config.theme.colors[k];
        if (typeof color === 'string') {
          options.push(escapeSpecialChars(k) + opacitySuffixes);
        } else {
          const variants = Object.keys(color).map((colorKey) => escapeSpecialChars(colorKey));
          const defaultIndex = variants.findIndex((v) => v === 'DEFAULT');
          const hasDefault = defaultIndex > -1;
          if (hasDefault) {
            variants.splice(defaultIndex, 1);
          }
          options.push(k + '(\\-(' + variants.join('|') + '))' + (hasDefault ? '?' : '') + opacitySuffixes);
        }
      });
      const arbitraryColors = [...color.mergedColorValues];
      switch (propName) {
        case 'fill':
          // Forbidden prefixes
          arbitraryColors.push(`(?!(angle|length|list)\:).{1,}`);
          break;
        case 'gradientColorStopPositions':
          arbitraryColors.push(color.RGBAPercentages); // RGBA % 0.5[%]
          arbitraryColors.push(color.optionalColorPrefixedVar);
          arbitraryColors.push(color.notHSLAPlusWildcard);
          break;
        case 'textColor':
          arbitraryColors.push(color.RGBAPercentages); // RGBA % 0.5[%]
          arbitraryColors.push(color.mandatoryColorPrefixed);
          break;
        default:
          arbitraryColors.push(color.mandatoryColorPrefixed);
      }
      options.push(`\\[(${arbitraryColors.join('|')})\\]`);
      return '(' + options.join('|') + ')';
    case 'borderSpacing':
    case 'borderWidth':
    case 'divideWidth':
    case 'fontSize':
    case 'outlineWidth':
    case 'outlineOffset':
    case 'ringWidth':
    case 'ringOffsetWidth':
    case 'textUnderlineOffset':
      escapedKeys.push(length.selectedUnitsRegEx);
      escapedKeys.push(length.anyCalcRegEx);
      // Mandatory `length:` prefix + wildcard
      escapedKeys.push(`\\[length\\:.{1,}\\]`);
      return '(' + escapedKeys.join('|') + ')';
    case 'strokeWidth':
      escapedKeys.push(length.selectedUnitsRegEx);
      escapedKeys.push(length.anyCalcRegEx);
      // Mandatory `length:` prefix + calc + wildcard
      escapedKeys.push(`\\[length\\:calc\\(.{1,}\\)\\]`);
      // Mandatory `length:` prefix + wildcard + optional units
      escapedKeys.push(`\\[length\\:(.{1,})(${length.selectedUnits.join('|')})?\\]`);
      return '(' + escapedKeys.join('|') + ')';
    case 'gap':
    case 'height':
    case 'lineHeight':
    case 'maxHeight':
    case 'size':
    case 'maxWidth':
    case 'minHeight':
    case 'minWidth':
    case 'padding':
    case 'width':
    case 'blur':
    case 'brightness':
    case 'contrast':
    case 'grayscale':
    case 'invert':
    case 'saturate':
    case 'sepia':
    case 'backdropBlur':
    case 'backdropBrightness':
    case 'backdropContrast':
    case 'backdropGrayscale':
    case 'backdropInvert':
    case 'backdropOpacity':
    case 'backdropSaturate':
    case 'backdropSepia':
    case 'transitionDuration':
    case 'transitionTimingFunction':
    case 'transitionDelay':
    case 'animation':
    case 'transformOrigin':
    case 'scale':
    case 'cursor':
      // All units
      escapedKeys.push(length.mergedUnitsRegEx);
      // Forbidden prefixes
      escapedKeys.push(`\\[(?!(angle|color|length|list)\:).{1,}\\]`);
      return '(' + escapedKeys.join('|') + ')';
    case 'backdropHueRotate':
    case 'hueRotate':
    case 'inset':
    case 'letterSpacing':
    case 'margin':
    case 'scrollMargin':
    case 'skew':
    case 'space':
    case 'textIndent':
    case 'translate':
      // All units
      escapedKeys.push(length.mergedUnitsRegEx);
      // Forbidden prefixes
      escapedKeys.push(`\\[(?!(angle|color|length|list)\:).{1,}\\]`);
      return '(' + escapedKeys.join('|') + ')';
    case 'backgroundOpacity':
    case 'borderOpacity':
    case 'opacity':
    case 'ringOpacity':
      // 0 ... .5 ... 1
      escapedKeys.push(`\\[(0(\\.\\d{1,})?|\\.\\d{1,}|1)\\]`);
      escapedKeys.push(length.anyCalcRegEx);
      // Unprefixed var()
      escapedKeys.push(`\\[var\\(\\-\\-[A-Za-z\\-]{1,}\\)\\]`);
      return '(' + escapedKeys.join('|') + ')';
    case 'rotate':
      escapedKeys.push(`\\[(${angle.mergedAngleValues.join('|')})\\]`);
      return '(' + escapedKeys.join('|') + ')';
    case 'gridTemplateColumns':
    case 'gridColumn':
    case 'gridColumnStart':
    case 'gridColumnEnd':
    case 'gridTemplateRows':
    case 'gridRow':
    case 'gridRowStart':
    case 'gridRowEnd':
    case 'gridAutoColumns':
    case 'gridAutoRows':
      // Forbidden prefixes
      escapedKeys.push(`\\[(?!(angle|color|length)\:).{1,}\\]`);
      return '(' + escapedKeys.join('|') + ')';
    case 'listStyleType':
      // Forbidden prefixes
      escapedKeys.push(`\\[(?!(angle|color|length|list)\:).{1,}\\]`);
      return '(' + escapedKeys.join('|') + ')';
    case 'objectPosition':
      // Forbidden prefixes
      escapedKeys.push(`\\[(?!(angle|color|length)\:).{1,}\\]`);
      return '(' + escapedKeys.join('|') + ')';
    case 'backgroundPosition':
    case 'boxShadow':
    case 'dropShadow':
    case 'transitionProperty':
      // Forbidden prefixes
      escapedKeys.push(`\\[(?!((angle|color|length|list)\:)|#|var\\().{1,}\\]`);
      return '(' + escapedKeys.join('|') + ')';
    case 'backgroundSize':
      // Forbidden prefixes
      escapedKeys.push(`\\[length\:.{1,}\\]`);
      return '(' + escapedKeys.join('|') + ')';
    case 'backgroundImageUrl':
      // Forbidden prefixes
      escapedKeys.push(`.{1,}`);
      return '(' + escapedKeys.join('|') + ')';
    case 'backgroundImage':
      // Forbidden prefixes
      escapedKeys.push(`\\[url\\(.{1,}\\)\\]`);
      return '(' + escapedKeys.join('|') + ')';
    case 'order':
    case 'zIndex':
      escapedKeys.push(genericArbitraryOption);
      return '(' + escapedKeys.join('|') + ')';
    case 'fontWeight':
    case 'typography':
    case 'lineClamp':
      // Cannot be arbitrary?
      return '(' + escapedKeys.join('|') + ')';
    case 'aspectRatio':
    case 'flexGrow':
    case 'flexShrink':
    case 'fontFamily':
    case 'flex':
    case 'borderRadius':
    default:
      escapedKeys.push(genericArbitraryOption);
      return '(' + escapedKeys.join('|') + ')';
  }
}
Generate the possible options for the RegEx

@param {String} propName The name of the prop e.g. textColor
@param {Array} keys Keys to be injected in the options
@param {Object} config Tailwind CSS Config
@param {Boolean} isNegative If the value is negative
@returns {String} Generated part of regex exposing the possible values