I think you suppose to use a pattern similar to this
Regex
(?<={% for[^%]*%})((?:.|\n)*)(?={% endfor %})
Explanation
(?<={% for[^%]*%}) : use lookbehind to searching for pattern {% for[^%]*%}
(?={% endfor %}) : use lookahead to searching for text {% endfor %}
((?:.|\n)*) : a message between a for loop which is captured by variable $1
But in case if your language do not support lookaround, you just use this
Regex
({% for[^%]*%})((?:.|\n)*)({% endfor %})
Explanation
({% for[^%]*%}) : capture pattern {% for[^%]*%} to variable $1
({% endfor %}) : capture pattern {% endfor %} to variable $3
((?:.|\n)*) : a message between a for loop which is captured by $2
Just modify my regex according to a restriction in your language then you will done this.
Edit
As I search, I think Javascript do not support lookaround and another thing {, } need to be escape by \. I already tested regex using some online regex tester for Javascript and I get this.
(\{% for[^%]*%\})((?:.|\n)*)(\{% endfor %\})
to get a text that you want, you just use variable $2.
Additional
In case you want to capture message inside nested loop e.g.
Example Message
{% for product in products.pos01 %}
...
{% for product in products.pos02 %}
"messages"
{% endfor %}
...
{% endfor %}
To capture "messages" inside this nested loop you just need to modify my previous regex to
(\{% for[^%]*%\}(?:.|\n)*\{% for[^%]*%\})((?:.|\n)*)(\{% endfor %\}(?:.|\n)*\{% endfor %\})
Explanation
(\{% for[^%]*%\}(?:.|\n)*\{% for[^%]*%\}) : means "start of for loop" following by "any characters including newline" and following by "start of for loop"
((?:.|\n)*): our target message
(\{% endfor %\}(?:.|\n)*\{% endfor %\}) : means "end of for loop" following by "any characters including newline" and following by "end of for loop"
Notice that I just rearrange my previous regex to done this little bit more complicated job.
\{%\s*for[\s\S]*?%}([\s\S]*?)\{%\s*endfor\s*%}?