find . -iname '*.zip' -print0 | xargs -0r zgrep -l -E 'PATTERN'
-iname rather than
-regex - it works as well for this and is, IMO, less confusing than
find's weird regex handling.
xargs -0 are used so that any filenames with spaces or shell metacharacters in them will be handled correctly.
-l option is documented in the man page:
Suppress normal output; instead print the name of each input
file from which output would normally have been printed. The
scanning will stop on the first match.
The first match mentioned is per file, so if multiple files match, they will all be printed. note that this means that grep will continue searching the other files, even after it has found one match.
If you want it to stop after the very first match, you could use
--line-buffered option and pipe grep's output into
head -1. When the first match is printed,
head will print it and terminate,
grep will no longer have a stdout so it will terminate, and
find will follow.
find . -iname '*.zip' -print0 | xargs -0r zgrep --line-buffered -l -E 'PATTERN' | head -1