If your data can contain multiple tags on a line, with unclosed tags in other positions than the last one, and the tag content can contain %, it's a little tricky:
Use /%(?:start|end){((?:(?!%(?:start|end){)[^}])+)/g and retrieve the first group.
Here is a regex101 test.
Note that it is about 3 times more expensive than the next two expressions, taking 112 steps to match your fourth data example, while the other two only take 34 steps.
If your data can contain multiple tags on a line, with unclosed tags in other positions than the last one, but the tag content can't contain %, it's already a lot easier :
Use /%(?:start|end){([^}%]+)/g and retrieve the first group.
Here is a regex101 test. Note how it fails on the last dataset.
If your data can't contain unclosed tags in other positions than the last one, it's even easier :
Use /%(?:start|end){([^}]+)/g and retrieve the first group.
Here is a regex101 test. Note that you will need to add linefeed characters to the negated class if you parse multiple lines at once, and also how it fails on the last two dataset.
/%start(.*?)%end/gi. What about 1 and 2? Are you sure 1 is%end{some textand notsome text}%end?