grep, that is g/re/p is a basic tool to print the lines that match a regular expression.
You want more here like a stream editor:
sed '/^begin$/,/^end$/!d'
or a more general text processing tool with an advanced language like awk, perl... as you already found out.
Having said that, some grep implementations can go a little further.
pcregrep -M '(?s)^begin$.*?^end$'
That's using the multi-line mode (-M); (?s) toggles the s flag in PCRE regexp so that . also matches newline characters.
With the current version of pcregrep, it's not guaranteed to work if the begin and end are more than 20kiB apart (or the specified buffer size).
For instance, it will match in
(seq 12091; echo begin; seq 4315; echo end; seq 10) |
   pcregrep -M '(?s)^begin$.*?^end$'
But not in:
(seq 12091; echo begin; seq 4316; echo end; seq 10) |
   pcregrep -M '(?s)^begin$.*?^end$'
Or with GNU grep built with PCRE support and assuming the file doesn't contain NUL characters:
grep -zoP  '(?ms)^begin$.*?^end$'
However that means that grep will load the entire file in memory before starting the search so should not be used except for small files. It also appends a NUL character to the output.
In any case, grep is not the right way to go here.
     
    
sedsame withawk:sed '/begin/,/end/! d' text