With perl:
$ perl -l -0777ne 'print $1 while /start_(.*?)_end/gs' your-example-2 text with start_and some
perl -n is the sed -n mode where the supplied expression is run for each line of the input like in sed. -l is for a newline to be automatically appended when printing¹ -<octal-number> sets the record separator to be the byte with the given value instead of newline. 0777 (511) or anything above 0377 (255) is a byte value that cannot exist, so there will be one any only one record: the whole file. *? like * matches 0 or more of the preceding atom (here . which matches any single character), but while * would match as many as possible, *? matches as few as possible, so that .*? will run until the first occurrence of _end, not the last. - the
s flag to the /regexp/ pattern matching operator is needed for . to also match on newline characters, which it doesn't by default.
You should be able to use pcregrep as well, however I find (with Debian's version 8.39 2016-06-14) that it gives:
$ pcregrep -Mo1 '(?s)start_(.*?)_end' your-example-2 text with start_and some and some
Which I can't explain. pcre2grep (version 10.42 2022-12-11) is OK though:
$ pcre2grep -Mo1 '(?s)start_(.*?)_end' your-example-2 text with start_and some
¹ Technically, it causes the record separator to be stripped from the input before storing in $_ and the output record separator ($\) to be set as the same as the input record separator ($/) which at that point is still newline, so it's important that that -l come before the -0.... Beware that -l<octal> sets the output record separator to the given byte value, so it's different from -l -<octal>.