Soultaker: Voor zover ik begrepen had legt de POSIX specificatie over regular expressions niet vast op welke manier die regular expressions uitgevoerd zouden moeten worden. Ik begrijp je betoog over POSIX/Traditional NFA's dan ook niet helemaal. Wat zijn de verschillen en waarom zou een POSIX-compliant regexp niet met een 'Traditional NFA' geparsed kunnen worden?
Sorry, in mijn tekst zat een fout. Traditional NFA's en POSIX NFA's kunnen
verschillende resultaten geven. Een DFA geeft hetzelfde resultaat als een POSIX NFA.
De POSIX standaard zegt dat wanneer er meerder mogelijke matches zijn de eerste (meest linker) genomen moet worden. Wanneer er meerdere matches mogelijk zijn op die positie moet de
langste van die matches genomen worden.
Dit betekent dat wanneer er een match gevonden is, er doorgezocht moet worden tot alle mogelijke matches gevonden zijn. Uit deze mogelijkheden zoeken we dan de langste en die verkiezen we tot winnaar.
Een Traditional NFA daarentegen kent alleen de 'leftmost' regel. Hij zal dus de eerste match pakken. Quantifiers zijn
wel greedy, dus in veel gevallen zul je geen verschil merken:
code:
1
| 'dit is een string, dit niet' =~ /dit (is)?/ |
De eerste 'dit' zal gevonden worden en omdat quantifiers (?) greedy zijn zal 'is' ook meegenomen worden in de match.
Leftmost gaat voor longest, dus in dit geval:
code:
1
| 'dit is een string, dit niet' =~ /dit (niet)?/ |
zal 'dit ' gematched worden (de eerste 'dit') en verder niets.
Wanneer zien we het verschil tussen een POSIX NFA en een Traditional NFA? Er is gemakkelijk een voorbeeldje te verzinnen:
code:
1
| 'ikloopniet' =~ /ik(loop)?(loopniet)?/ |
Een Traditional NFA matcht 'ikloop', het is de leftmost match en de quantifier is greedy. Een POSIX NFA is nog niet tevreden en zoekt verder. Uiteindelijk zal hij 'ikloopniet' matchen, hier zien we dus een belangrijk verschil!
Op deze manier kun je gemakkelijk testen of je met een POSIX of Traditional NFA te doen hebt.
Ik ken vrijwel geen tools met een POSIX NFA (lex, mawk en er schijnt een POSIX NFA implementatie van GNU Emacs te zijn).
Een DFA is weer een ander verhaal. Een DFA engine is erg snel, maar doordat hij fundamenteel anders werkt is hij in veel gevallen niet nuttig. Na een match kan er geen informatie over de match aanwezig zijn (waar er gematched is, inhoud van parentheses), hierdoor zijn ook backreferences niet mogelijk. Verder is bijvoorbeeld lookahead niet mogelijk, of een non-greedy quantifier.
Een DFA kan wel goed gebruikt worden om heel snel te zien
of er een match is. Als er dan een match is, wordt de NFA ingezet om er verder dingen mee te doen. Van deze methode maken enkele tools gebruik.
Het leek me zelf ook logisch om uitsluitend met DFA's te werken, in verband met de veel efficientere executie ten koste van een klein beetje geheugenruimte. Volgens jou gebeurd dat echter niet; wat is de reden daarvoor?
Ah, dat moet nu duidelijk zijn

Mijn punt was trouwens dat moderne POSIX regexps (waarschijnlijk) goed door Perl verwerkt worden en niet dat alle in Perl mogelijke regexps POSIX-compliant zijn (wat niet zo is, aangezien Perl veel meer functionaliteit biedt).
Ze zullen het zeker doen, maar zoals je ziet kun je dus voor verrassingen komen te staan.
Inderdaad en nog wel tientallen andere POSIX standaarden, maar daar hadden we 't nu niet over.

Daar hadden we het juist wel over
POSIX locale lijkt me juist voor regexen een erg belangrijke standaard. Voldoet een DFA of POSIX NFA (DFA is per definitie POSIX) niet aan de POSIX locale, dan is ie niet POSIX compliant. Regexen is all about text, localisation lijkt me daar een niet al te triviaal punt.