diff --git a/src/backend/regex/regcomp.c b/src/backend/regex/regcomp.c
index 9afdf75905f..41f00d991e1 100644
--- a/src/backend/regex/regcomp.c
+++ b/src/backend/regex/regcomp.c
@@ -958,7 +958,7 @@ parseqatom(struct vars *v,
 			if (cap)
 			{
 				v->subs[subno] = atom;
-				t = subre(v, '(', atom->flags | CAP, lp, rp);
+				t = subre(v, '(', atom->flags | CAP, s, s2);
 				NOERR();
 				t->subno = subno;
 				t->left = atom;
@@ -1041,11 +1041,23 @@ parseqatom(struct vars *v,
 	/* annoying special case:  {0} or {0,0} cancels everything */
 	if (m == 0 && n == 0)
 	{
-		if (atom != NULL)
-			freesubre(v, atom);
-		if (atomtype == '(')
-			v->subs[subno] = NULL;
-		delsub(v->nfa, lp, rp);
+		/*
+		 * If we had capturing subexpression(s) within the atom, we don't want
+		 * to destroy them, because it's legal (if useless) to back-ref them
+		 * later.  Hence, just unlink the atom from lp/rp and then ignore it.
+		 */
+		if (atom != NULL && (atom->flags & CAP))
+		{
+			delsub(v->nfa, lp, atom->begin);
+			delsub(v->nfa, atom->end, rp);
+		}
+		else
+		{
+			/* Otherwise, we can clean up any subre infrastructure we made */
+			if (atom != NULL)
+				freesubre(v, atom);
+			delsub(v->nfa, lp, rp);
+		}
 		EMPTYARC(lp, rp);
 		return;
 	}
diff --git a/src/test/regress/expected/regex.out b/src/test/regress/expected/regex.out
index 8f4626f41da..09afccc98cf 100644
--- a/src/test/regress/expected/regex.out
+++ b/src/test/regress/expected/regex.out
@@ -567,6 +567,25 @@ select 'a' ~ '()+\1';
  t
 (1 row)
 
+-- Test incorrect removal of capture groups within {0}
+select 'xxx' ~ '(.){0}(\1)' as f;
+ f 
+---
+ f
+(1 row)
+
+select 'xxx' ~ '((.)){0}(\2)' as f;
+ f 
+---
+ f
+(1 row)
+
+select 'xyz' ~ '((.)){0}(\2){0}' as t;
+ t 
+---
+ t
+(1 row)
+
 -- Test ancient oversight in when to apply zaptreesubs
 select 'abcdef' ~ '^(.)\1|\1.' as f;
  f 
diff --git a/src/test/regress/sql/regex.sql b/src/test/regress/sql/regex.sql
index 762b3ae69b2..758de44d2f4 100644
--- a/src/test/regress/sql/regex.sql
+++ b/src/test/regress/sql/regex.sql
@@ -135,6 +135,11 @@ select 'a' ~ '.. ()|\1';
 select 'a' ~ '()*\1';
 select 'a' ~ '()+\1';
 
+-- Test incorrect removal of capture groups within {0}
+select 'xxx' ~ '(.){0}(\1)' as f;
+select 'xxx' ~ '((.)){0}(\2)' as f;
+select 'xyz' ~ '((.)){0}(\2){0}' as t;
+
 -- Test ancient oversight in when to apply zaptreesubs
 select 'abcdef' ~ '^(.)\1|\1.' as f;
 select 'abadef' ~ '^((.)\2|..)\2' as f;