|
|||||||||||||||||||||||||||
On Tue, Aug 06, 2002 at 11:22:08AM +0200, Peter Makholm wrote:
> "Simon B. Nielsen" <sslug@sslug> writes:
>
> > Jeg skal lave et simpelt tjek der skal se om min streng indeholder præcist 6
> > tegn hvor 3 af dem er tal og de 3 andre bogstaver.
>
> ( m/^[0-9A-ZÆØÅa-zæøå]{6}$/ && (y/0-9// == 3) && (y/A-ZÆØÅa-zæøå// == 3) )
>
> Desvære kan man ikke bruge klasser af tegn i y///.
>
Hvis du ønsker at bruge tegnklasser kan du tælle tegn med m//g, men det
er lidt mere besværligt.
Først skal du evaluere m//g i en list context og derefter bede om
længden af listen.
use locale;
@a = (m/[[:alpha:]]/g); # giver liste af tegn jf. localet
$count = scalar(@a); # giver antallet af tegn
Man kan godt slå de to trin sammen, men det kræve nogle krumspring for
at sikre den rigtige evaluerings-kontekst for hver del:
use locale;
$count = scalar(grep {1} (m/[[:alpha:]]/g));
grep tvinger evaluering af m//g i list context, hvorefter scalar giver
dig længden af listen. (Er der nogen der kan finde en bedre måde at
tving evaluering i list context end en dummy grep eller map?)
Den generelle udgave af Peters svar er så
use locale;
( m/^[[:alnum:]]{6}$/
&& (scalar(grep {1} (m/[[:alpha:]]/g)) == 3)
&& (scalar(grep {1} (m/[[:digit:]]/g)) == 3))
Jeg vil anbefale at du lader din kode følge af en kommentar, der
forklarer hvad det er du laver, for helt intuitivt er det ikke for de
fleste.
Det korte af det lange er at hvis du ikke har brug for locale support,
så er du bedre stillet med Peters forslag. Det er hurtigere og
simplere. Hvis din kode skal kunne håndtere tekster på andre sprog, så
bør du gøre noget som ovenstående.
--
René Seindal (sslug@sslug) http://www.seindal.dk/rene/
|
||||||||||||||
|
||||||||||||||