diff --git a/lib/config/validation.ts b/lib/config/validation.ts
index a61a2805c4c908de57fde848cbc4ca1f8d165f53..8af02bc81f295ec06f84dda600fe978455530d53 100644
--- a/lib/config/validation.ts
+++ b/lib/config/validation.ts
@@ -1,6 +1,6 @@
 import is from '@sindresorhus/is';
 import { getManagerList } from '../manager';
-import { regEx } from '../util/regex';
+import { configRegexPredicate, isConfigRegex, regEx } from '../util/regex';
 import * as template from '../util/template';
 import { hasValidSchedule, hasValidTimezone } from '../workers/branch/schedule';
 import { RenovateConfig, ValidationMessage } from './common';
@@ -144,31 +144,8 @@ export async function validateConfig(
             message: `Invalid ${currentPath}: \`${errorMessage}\``,
           });
         }
-      } else if (
-        key === 'allowedVersions' &&
-        is.string(val) &&
-        val.length > 1 &&
-        val.startsWith('/') &&
-        val.endsWith('/')
-      ) {
-        try {
-          regEx(val.slice(1, -1));
-        } catch (err) {
-          errors.push({
-            depName: 'Configuration Error',
-            message: `Invalid regExp for ${currentPath}: \`${val}\``,
-          });
-        }
-      } else if (
-        key === 'allowedVersions' &&
-        is.string(val) &&
-        val.length > 2 &&
-        val.startsWith('!/') &&
-        val.endsWith('/')
-      ) {
-        try {
-          regEx(val.slice(2, -1));
-        } catch (err) {
+      } else if (key === 'allowedVersions' && isConfigRegex(val)) {
+        if (!configRegexPredicate(val)) {
           errors.push({
             depName: 'Configuration Error',
             message: `Invalid regExp for ${currentPath}: \`${val}\``,
diff --git a/lib/util/regex.ts b/lib/util/regex.ts
index 64bdbb6b7f3f35c3d4f293fa4a530de349a2263f..e4c9be2fb0f63cdaaf8848586abfbf648d4643c0 100644
--- a/lib/util/regex.ts
+++ b/lib/util/regex.ts
@@ -1,3 +1,4 @@
+import is from '@sindresorhus/is';
 import { CONFIG_VALIDATION } from '../constants/error-messages';
 import { logger } from '../logger';
 
@@ -29,3 +30,38 @@ export function regEx(pattern: string, flags?: string): RegExp {
 export function escapeRegExp(input: string): string {
   return input.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
 }
+
+const configValStart = /^!?\//;
+const configValEnd = /\/$/;
+
+export function isConfigRegex(input: unknown): input is string {
+  return (
+    is.string(input) && configValStart.test(input) && configValEnd.test(input)
+  );
+}
+
+function parseConfigRegex(input: string): RegExp | null {
+  try {
+    const regexString = input
+      .replace(configValStart, '')
+      .replace(configValEnd, '');
+    return regEx(regexString);
+  } catch (err) {
+    // no-op
+  }
+  return null;
+}
+
+type ConfigRegexPredicate = (string) => boolean;
+
+export function configRegexPredicate(input: string): ConfigRegexPredicate {
+  const configRegex = parseConfigRegex(input);
+  if (configRegex) {
+    const isPositive = !input.startsWith('!');
+    return (x: string): boolean => {
+      const res = configRegex.test(x);
+      return isPositive ? res : !res;
+    };
+  }
+  return null;
+}
diff --git a/lib/workers/repository/process/lookup/filter.ts b/lib/workers/repository/process/lookup/filter.ts
index af92486c3a82280d610dc17efe6218560c56b326..7f6c8be91fdfcde284159abc3256ea215695f51e 100644
--- a/lib/workers/repository/process/lookup/filter.ts
+++ b/lib/workers/repository/process/lookup/filter.ts
@@ -2,7 +2,7 @@ import * as semver from 'semver';
 import { CONFIG_VALIDATION } from '../../../../constants/error-messages';
 import { Release } from '../../../../datasource';
 import { logger } from '../../../../logger';
-import { regEx } from '../../../../util/regex';
+import { configRegexPredicate, isConfigRegex } from '../../../../util/regex';
 import * as allVersioning from '../../../../versioning';
 import * as npmVersioning from '../../../../versioning/npm';
 import * as pep440 from '../../../../versioning/pep440';
@@ -18,8 +18,6 @@ export interface FilterConfig {
   versioning: string;
 }
 
-const regexes: Record<string, RegExp> = {};
-
 export function filterVersions(
   config: FilterConfig,
   fromVersion: string,
@@ -74,25 +72,10 @@ export function filterVersions(
   }
 
   if (allowedVersions) {
-    if (
-      allowedVersions.length > 1 &&
-      allowedVersions.startsWith('/') &&
-      allowedVersions.endsWith('/')
-    ) {
-      regexes[allowedVersions] =
-        regexes[allowedVersions] || regEx(allowedVersions.slice(1, -1));
-      filteredVersions = filteredVersions.filter((v) =>
-        regexes[allowedVersions].test(v.version)
-      );
-    } else if (
-      allowedVersions.length > 2 &&
-      allowedVersions.startsWith('!/') &&
-      allowedVersions.endsWith('/')
-    ) {
-      regexes[allowedVersions] =
-        regexes[allowedVersions] || regEx(allowedVersions.slice(2, -1));
-      filteredVersions = filteredVersions.filter(
-        (v) => !regexes[allowedVersions].test(v.version)
+    if (isConfigRegex(allowedVersions)) {
+      const isAllowed = configRegexPredicate(allowedVersions);
+      filteredVersions = filteredVersions.filter(({ version }) =>
+        isAllowed(version)
       );
     } else if (versioning.isValid(allowedVersions)) {
       filteredVersions = filteredVersions.filter((v) =>
diff --git a/lib/workers/repository/process/lookup/index.spec.ts b/lib/workers/repository/process/lookup/index.spec.ts
index accb10cceb717bcc5f3189b9e632b255aa196b6d..f0614a7af96d4a1790df69559d3b7f26e7b9c6c0 100644
--- a/lib/workers/repository/process/lookup/index.spec.ts
+++ b/lib/workers/repository/process/lookup/index.spec.ts
@@ -161,7 +161,7 @@ describe('workers/repository/process/lookup', () => {
       nock('https://registry.npmjs.org').get('/q').reply(200, qJson);
       expect((await lookup.lookupUpdates(config)).updates).toHaveLength(1);
     });
-    it('enforces allowedVersions with negativee regex', async () => {
+    it('enforces allowedVersions with negative regex', async () => {
       config.currentValue = '0.4.0';
       config.allowedVersions = '!/^1/';
       config.depName = 'q';