Een vraagje ... is het mogelijk (en zo ja hoe) om via een regex dubbele tekens af te keuren?
Wat ik graag zou willen is dat ik bijv. kan aangeven dat er letters en cijfers gebruikt mogen worden, en spaties, punten en streepjes. Dan krijg je zoiets:
pattern="^[- .0-9A-Za-z]$"
Maar ik wil niet dat men dubbele spaties, streepjes en punten kan gebruiken.
Dus dit mag wel: Ozzie.PHP-Hulp
Maar dit niet: Ozzie..PHP--Hulp
Is het mogelijk om in een regex aan te geven dat er alleen 'enkele' streepjes, spaties en punten gebruikt mogen worden?
Oftewel: Een alnum, gevolgd door of een alnum of een speciaal teken die op zijn minst weer wordt gevolgd door een alnum. En dat laatste dan 0 of meer keer. Misschien iets leesbaarder in een parsing grammer syntax:
Ja, dat kun je veranderen. En ik zou zeggen dat de eerste wellicht wat sneller zou zijn, aangezien de tweede een geneste optional quantifier heeft (? en *). Hierdoor moet de engine in het geval van een non-match veel backtracking toepassen, wat het geheel trager zou maken.
Maar voor simpele HTML5 input validatie is dat allemaal over-optimalisatie. En zou dan wel voor jouw optie kiezen, een stuk leesbaarder naar mijn idee.
Ik wil eigenlijk toch terug naar de eerste variant die jij had voorgesteld. Dus geen dezelfde vreemde tekens achter elkaar, maar verschillende vreemde tekens achter elkaar mag wel.
Dus niet 2x een spatie achter elkaar maar een punt en een spatie mag bijvoorbeeld wel.
Ik vond dit zelf wel een hele toffe oplossing van jou:
([.\s-]) # punt, spatie en streepje
(?!\1) # niet gevolgt door hetzelfde teken
Het enige nadeel is nu dat ik na een punt, streepje of spatie een gek teken kan zetten. Je zou dus bijvoorbeeld .* kunnen doen, terwijl een sterretje niet is toegestaan.
Wat ik dus zou willen, is dit:
We hebben vreemde tekens: [.\s-]
En cijfers en letters: [0-9a-zA-Z]
Cijfers en letters mogen gewoon achter elkaar. Geen enkel probleem.
Maar een vreemd tegen moet gevolgd worden door óf een cijfer of letter óf een ANDER vreemd teken.
Is dat op een handige manier te doen? Het mooiste zou zijn als je kunt zeggen ... een vreemd teken moet gevolgd worden door [.-\s0-9a-zA-Z] maar dan zonder datzelfde vreemde teken. Ik kan wel voor ieder vreemd teken een aparte groep maken waar dat teken door gevolgd moet worden, maar dan wordt de regex zo enorm lang (in de praktijk zijn het zelfs nog een paar meer vreemde tekens).
Maar goed, dus even samengevat.
Cijfers en letters mogen elkaar gewoon opvolgen, maar een vreemd teken mag niet door datzelfde vreemde teken worden gevolgd, maar wel door een ander vreemd teken of een cijfer of letter.
Weet je daar nog iets voor? Dat zou geweldig zijn.
Look arounds zijn zero-length assertions. Deze worden dus wel gematched, maar zorgen dus niet voor het consumen van de gematchde string. Dus /^(?:(\w)(?!\1))+$/ zal een string matchen als deze volledig bestaat uit woord tekens (de \w) terwijl deze niet opgevolgd worden door hetzelfde teken (het (?!\1) gedeelte).
Dus ([.\s-])(?!\1) matched alleen de punt, spatie of streepje. Niet het teken daarna (het controleert alleen of het teken daarna niet hetzelfde teken is). Dus /^(?:[a-zA-Z0-9]|([.\s-])(?!\1|$))+$/ zal moeten werken naar mijn idee.
In plaats van a-zA-Z zou je ook simpelweg a-z kunnen gebruiken in combinatie met de /i switch (flag) voor case-insensitive matching.
Mogelijk zou je ook aan een alternatieve oplossing kunnen denken waarbij je niet-legale karakters replaced (maar vermijd blacklists omdat je dan mogelijk niet alle ongewenste gevallen vangt) en dan na afloop deze (potentieel aangepaste) string vergelijkt met het origineel. Indien de twee strings verschillen wil dat zeggen dat er illegale karakters gestript zijn en dus dat de invoer ongeldig was.
Bij het zoeken naar een oplossing ben je niet per definitie beperkt tot de kaders van je regexp. En mogelijk maakt dat het regexp-deel een stuk eenvoudiger ;).
>> In plaats van a-zA-Z zou je ook simpelweg a-z kunnen gebruiken in combinatie met de /i switch (flag) voor case-insensitive matching.
Thanks, ik zal dat straks nog eens proberen, hoewel ik meen ergens gelezen te hebben dat dat voor een html5 input pattern niet werkt, maar zeker weten doe ik dat niet meer.
>> Bij het zoeken naar een oplossing ben je niet per definitie beperkt tot de kaders van je regexp. En mogelijk maakt dat het regexp-deel een stuk eenvoudiger ;).
Klopt inderdaad, maar in sommige situaties vind ik een regex wel de "mooiere" oplossing. Vooral omdat het hier echt om een bepaald patroon gaat, en in mindere mate om de vraag 'zit dat teken er wel of niet in'. Maar wat je zegt klopt zeker. Er zijn meerdere mogelijkheden.