diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md
index 3de149ac8ce186cd18f0ba7ba340d50d631b9333..0bc3da808d4393f8c0c3915c39d4df64f55f8f08 100644
--- a/docs/usage/configuration-options.md
+++ b/docs/usage/configuration-options.md
@@ -2027,6 +2027,8 @@ All matches of the first `matchStrings` pattern are detected, then each of these
 If the next `matchStrings` pattern has multiple matches then it will split again.
 This process will be followed as long there is a match plus a next `matchingStrings` pattern is available or a dependency is detected.
 
+Matched groups will be available in subsequent matching layers.
+
 This is an example how this can work.
 The first regex manager will only upgrade `grafana/loki` as looks for the `backup` key then looks for the `test` key and then uses this result for extraction of necessary attributes.
 However, the second regex manager will upgrade both definitions as its first `matchStrings` matches both `test` keys.
diff --git a/lib/manager/regex/__snapshots__/index.spec.ts.snap b/lib/manager/regex/__snapshots__/index.spec.ts.snap
index bcc3505484bc79b2b36816fcf4b72740cb5599dd..c5f0f8e34fe21c35aed20febbd256f3ef375065a 100644
--- a/lib/manager/regex/__snapshots__/index.spec.ts.snap
+++ b/lib/manager/regex/__snapshots__/index.spec.ts.snap
@@ -311,6 +311,52 @@ exports[`manager/regex/index extracts with recursive strategy and fail because o
 
 exports[`manager/regex/index extracts with recursive strategy and fail because there is no match 1`] = `null`;
 
+exports[`manager/regex/index extracts with recursive strategy and merged groups 1`] = `
+Object {
+  "depNameTemplate": "{{{ first }}}/{{{ second }}}/{{{ depName }}}",
+  "deps": Array [
+    Object {
+      "currentValue": "v2.19.0",
+      "datasource": "docker",
+      "depName": "group1/group1/prom/prometheus",
+      "replaceString": "\\"name\\": \\"prom/prometheus\\",
+    \\"type\\": \\"docker\\",
+    \\"value\\": \\"v2.19.0\\"",
+    },
+    Object {
+      "currentValue": "7.2.2",
+      "datasource": "docker",
+      "depName": "group2/group2/grafana/grafana",
+      "replaceString": "\\"name\\": \\"grafana/grafana\\",
+    \\"type\\": \\"docker\\",
+    \\"value\\": \\"7.2.2\\"",
+    },
+    Object {
+      "currentValue": "1.6.1",
+      "datasource": "docker",
+      "depName": "backup/backup/grafana/loki",
+      "replaceString": "\\"name\\": \\"grafana/loki\\",
+      \\"type\\": \\"docker\\",
+      \\"value\\": \\"1.6.1\\"",
+    },
+    Object {
+      "currentValue": "3.9.0",
+      "datasource": "docker",
+      "depName": "setup/setup/python",
+      "replaceString": "\\"name\\": \\"python\\",
+      \\"type\\": \\"docker\\",
+      \\"value\\": \\"3.9.0\\"",
+    },
+  ],
+  "matchStrings": Array [
+    "\\"(?<first>[^\\"]*)\\":\\\\s*{[^}]*}",
+    "\\"(?<second>[^\\"]*)\\":\\\\s*\\\\{[^}]*}",
+    "\\"name\\":\\\\s*\\"(?<depName>.*)\\"[^\\"]*\\"type\\":\\\\s*\\"(?<datasource>.*)\\"[^\\"]*\\"value\\":\\\\s*\\"(?<currentValue>.*)\\"",
+  ],
+  "matchStringsStrategy": "recursive",
+}
+`;
+
 exports[`manager/regex/index extracts with recursive strategy and multiple layers  1`] = `
 Object {
   "deps": Array [
diff --git a/lib/manager/regex/index.spec.ts b/lib/manager/regex/index.spec.ts
index 13258f85f2d53de66a00baadb9c6589a73ed5775..cec3ca01d3bff9a156da35faf83e1268dda6d3c4 100644
--- a/lib/manager/regex/index.spec.ts
+++ b/lib/manager/regex/index.spec.ts
@@ -350,4 +350,22 @@ describe('manager/regex/index', () => {
     expect(res).toMatchSnapshot();
     expect(res).toBeNull();
   });
+  it('extracts with recursive strategy and merged groups', async () => {
+    const config: CustomExtractConfig = {
+      matchStrings: [
+        '"(?<first>[^"]*)":\\s*{[^}]*}',
+        '"(?<second>[^"]*)":\\s*\\{[^}]*}',
+        '"name":\\s*"(?<depName>.*)"[^"]*"type":\\s*"(?<datasource>.*)"[^"]*"value":\\s*"(?<currentValue>.*)"',
+      ],
+      matchStringsStrategy: 'recursive',
+      depNameTemplate: '{{{ first }}}/{{{ second }}}/{{{ depName }}}',
+    };
+    const res = await extractPackageFile(
+      exampleJsonContent,
+      'example.json',
+      config
+    );
+    expect(res).toMatchSnapshot();
+    expect(res.deps).toHaveLength(4);
+  });
 });
diff --git a/lib/manager/regex/index.ts b/lib/manager/regex/index.ts
index 7a866a6f70e4323b994edd4156c82536b7578853..4558010c2c688c69b101c3720088c0eb54e261e8 100644
--- a/lib/manager/regex/index.ts
+++ b/lib/manager/regex/index.ts
@@ -121,21 +121,17 @@ function mergeGroups(
   mergedGroup: Record<string, string>,
   secondGroup: Record<string, string>
 ): Record<string, string> {
-  const resultGroup = {};
+  const resultGroup = Object.create(null); // prevent prototype pollution
 
-  Object.keys(mergedGroup)
-    .filter((key) => validMatchFields.includes(key)) // prevent prototype pollution
-    .forEach(
-      // eslint-disable-next-line no-return-assign
-      (key) => (resultGroup[key] = mergedGroup[key])
-    );
-  Object.keys(secondGroup)
-    .filter((key) => validMatchFields.includes(key)) // prevent prototype pollution
-    .forEach((key) => {
-      if (secondGroup[key] && secondGroup[key] !== '') {
-        resultGroup[key] = secondGroup[key];
-      }
-    });
+  Object.keys(mergedGroup).forEach(
+    // eslint-disable-next-line no-return-assign
+    (key) => (resultGroup[key] = mergedGroup[key])
+  );
+  Object.keys(secondGroup).forEach((key) => {
+    if (secondGroup[key] && secondGroup[key] !== '') {
+      resultGroup[key] = secondGroup[key];
+    }
+  });
   return resultGroup;
 }
 
@@ -172,7 +168,8 @@ function handleRecursive(
   content: string,
   packageFile: string,
   config: CustomExtractConfig,
-  index = 0
+  index = 0,
+  combinedGroups: Record<string, string> = {}
 ): PackageDependency[] {
   const regexes = config.matchStrings.map((matchString) =>
     regEx(matchString, 'g')
@@ -184,9 +181,20 @@ function handleRecursive(
   return regexMatchAll(regexes[index], content).flatMap((match) => {
     // if we have a depName and a currentValue with have the minimal viable definition
     if (match?.groups?.depName && match?.groups?.currentValue) {
-      return createDependency(match, null, config);
+      return createDependency(
+        match,
+        mergeGroups(combinedGroups, match.groups),
+        config
+      );
     }
-    return handleRecursive(match[0], packageFile, config, index + 1);
+
+    return handleRecursive(
+      match[0],
+      packageFile,
+      config,
+      index + 1,
+      mergeGroups(combinedGroups, match.groups || {})
+    );
   });
 }