Lex/Flex, wich I think we can agree is used by "actual code that's written using normal languages" use DFAs, both inside rules and between rules, and they do not try '|' cases left to right (They probably could have if they wanted since there is a REJECT action that already force them to store the list of all the rules/texts that were matched):
a|ab {cout << "matched ab" << std::endl; } b { cout << "matched b" << std::endl; }
if provided with "ab", will match the first rule with "ab", and not the first with "a" then the second with "b".