diff --git a/src/backend/regex/regexec.c b/src/backend/regex/regexec.c
index 7f41437cb5..5e78f8149c 100644
--- a/src/backend/regex/regexec.c
+++ b/src/backend/regex/regexec.c
@@ -1190,6 +1190,10 @@ creviterdissect(struct vars * v,
 			(k >= min_matches || min_matches - k < end - limit))
 			limit++;
 
+		/* if this is the last allowed sub-match, it must reach to the end */
+		if (k >= max_matches)
+			limit = end;
+
 		/* try to find an endpoint for the k'th sub-match */
 		endpts[k] = shortest(v, d, endpts[k - 1], limit, end,
 							 (chr **) NULL, (int *) NULL);
diff --git a/src/test/regress/expected/regex.out b/src/test/regress/expected/regex.out
index df39ef937d..497ddcd467 100644
--- a/src/test/regress/expected/regex.out
+++ b/src/test/regress/expected/regex.out
@@ -188,3 +188,11 @@ select regexp_matches('Programmer', '(\w)(.*?\1)', 'g');
  {m,m}
 (2 rows)
 
+-- Test for proper matching of non-greedy iteration (bug #11478)
+select regexp_matches('foo/bar/baz',
+                      '^([^/]+?)(?:/([^/]+?))(?:/([^/]+?))?$', '');
+ regexp_matches 
+----------------
+ {foo,bar,baz}
+(1 row)
+
diff --git a/src/test/regress/sql/regex.sql b/src/test/regress/sql/regex.sql
index e5f690263b..ceb9d699ce 100644
--- a/src/test/regress/sql/regex.sql
+++ b/src/test/regress/sql/regex.sql
@@ -46,3 +46,7 @@ select 'a' ~ '((((((a+|)+|)+|)+|)+|)+|)';
 -- https://core.tcl.tk/tcl/tktview/6585b21ca8fa6f3678d442b97241fdd43dba2ec0
 select 'Programmer' ~ '(\w).*?\1' as t;
 select regexp_matches('Programmer', '(\w)(.*?\1)', 'g');
+
+-- Test for proper matching of non-greedy iteration (bug #11478)
+select regexp_matches('foo/bar/baz',
+                      '^([^/]+?)(?:/([^/]+?))(?:/([^/]+?))?$', '');