Skrivet av Pelle:
detta fungerade: "/@([\wÅÄÖåäö]{4,15})/"
Här finns en liten fälla som kan vara värd att känna till om du inte redan gör det, men då kanske det kan vara till nytta för någon annan: preg-funktionerna kommer tolka de tecken som ser ut som "åäö" i din editor binärt och beroende på vilken teckenkodning du sparat källfilen med. Om du sparat den med en teckenkodning som bara använder en byte per tecken (t.ex. ISO 8859-1) så är det motsvarande bytes {E5,E4,F6}
, men om du nu skickar in en sträng avsedd att tolkas som ISO 8859-7 så kommer den glatt matcha "δεφ".
Men, utbrister du med bestörtning, man ska inte blanda teckenkodningar! — och det är helt riktigt, men många editorer kommer spara källfilen som UTF-8, och nu blir det rikigt spännande: Ett "å" representeras nu av flera bytes, antingen {C3,A5}
(å) eller {61,CC,8A}
(a + kombinerande ring), beroende på, och när pcre läser detta byte för byte så kommer dit mönster tolkas som att det ska acceptera allt som består av "ord-tecken" (beroende på din locale) samt i värsta fall någon kombination av {61,6F,8A,84,85,88,96,A4,A5,B6,C3,CC}
. Dessutom kommer den matcha ofullständiga tecken: Om du har bjudit över dansken på øl (ø = {C3,B8}
) så kommer den första byten se giltig ut och inkluderas i träffen, men inte den andra, och din data är nu trasig. Oups
Så, vad är lösningen? Kontrollera vilken teckenkodning du arbetar med (din editor har antagligen någon inställning för det), och sedan:
Är det en typ som endast använder en byte per tecken så se till att källfilen och datan använder samma, eller om det inte är möjligt använd ersättningstecken (skriv det tecken i källfilskodningen vars värde motsvarar det i datan) eller skriv in värdet direkt med en escapesekvens.
Är det UTF-8 så använd modiferaren "u" för att instruera pcre att behandla både mönster och data som det. Observera att om du använder modifieraren på en sträng som inte är av giltigt format så kommer det orsaka en varning, men om du glömmer det på ett mönster med multibytetecken kommer tyst accepteras, och inte göra vad du avsett... Vanligtvis försöker man använda UTF-8 överallt och blir ditt mönster helt enkelt "/@([\wÅÄÖåäö]{4,15})/u"
istället. Mycket väsen för liten ändring alltså.
Är det något annat så konvertera till UTF-8.