Statements that sneakily alter the control flow are indeed bad style.
There are many alternative forms to choose from.
- You could set a flag and test that after the s///.
- Or a chain of m/\G.../g.
- You could embed the test condition in the regular expression:
s/\$(\w++)(?(?{ !defined $defs{$^N} })(?!))/$defs{$1}/; Care must be taken that the whole text is matched: use anchors, possessive matching, etc.
- But if the %defs are not dynamic, the much simpler, and probably faster, approach is to construct the regex from your defs so that only valid tokens are accepted.
- Use something more capable for parsing, like Marpa.
Bottom line is, it sounds like you really need a lexer/scanner, not contorted regexes. Could you give more information pertaining to the problem at hand (the purpose of the wheel you're building)?