As @aranchelk said LL and LR grammars are literally that. They allow you to assign names to regexs and compose them.
Libraries like python's lrparsing [0] let you assign regex's (aka tokens) to variables, then build grammars by combining them using python expressions. For example:
while_statement = Keyword('while') + '(' + expression + ')' + block
statement = while_statement | ....
block = Token('{') + Repeat(statement + ';') + Token('}')
These grammars are more complex, with more rules you have to follow, but also more checking is done when they are compiled. They tend to mostly work once they do compile. So they are what you asked for, but there is no free lunch.
On the down side, lrparsing is pure python so it's slower than python's inbuilt regex's.
[0] https://lrparsing.sourceforge.net/