gamin@ireq-robot.hydro.qc.ca (Martin Boyer) (02/02/91)
I'm trying to compare a numeric user id against a list of numbers. Here's my attempt; it doesn't work, possibly because the regular expression search doesn't treat the numbers as strings: $uid_list = "13|1"; $this_uid = 101; if ($this_uid =~ /^$uid_list$/o) { print "Matches!\n"; } else { print "Doesn't match.\n"; } This section prints Matches!, but that's not what I want; what I want is for the test to succeed only for values of 13 or 1. Can anybody enlighten me? Thanks, -- Martin Boyer mboyer@ireq-robot.hydro.qc.ca Institut de recherche d'Hydro-Quebec mboyer@ireq-robot.uucp Varennes, QC, Canada J3X 1S1 +1 514 652-8412
lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (02/02/91)
In article <5152@s3.ireq.hydro.qc.ca> gamin@ireq-robot.hydro.qc.ca (Martin Boyer) writes: : : I'm trying to compare a numeric user id against a list of numbers. : Here's my attempt; it doesn't work, possibly because the regular : expression search doesn't treat the numbers as strings: : : $uid_list = "13|1"; : : $this_uid = 101; : : if ($this_uid =~ /^$uid_list$/o) { : print "Matches!\n"; : } else { : print "Doesn't match.\n"; : } : : This section prints Matches!, but that's not what I want; what I want : is for the test to succeed only for values of 13 or 1. Well, look at the pattern you're actually searching for: /^13|1$/ Note that ^ and $ don't automatically distribute over alternatives. /1$/ matches 101. You want /^(13|1)$/. So say /^($uid_list)$/ and it should work. Note that this is essentially a linear search. If you're doing lots of comparisons against a longish list, it'll be much faster to load up an array to check with: for (split(/\|/, $uid_list)) { # or equivalent $valid_uid[$_] = 1; } ... if ($valid_uid[$this_uid]) { ... If your uids get too large to use a normal array, use an associative array instead. A vec() would also work, and save a lot of space over a normal array: if (vec($valid_uid, $this_uid, 1)) { ... Larry
merlyn@iwarp.intel.com (Randal L. Schwartz) (02/02/91)
In article <5152@s3.ireq.hydro.qc.ca>, gamin@ireq-robot (Martin Boyer) writes: | $uid_list = "13|1"; | | $this_uid = 101; | | if ($this_uid =~ /^$uid_list$/o) { | print "Matches!\n"; | } else { | print "Doesn't match.\n"; | } | | This section prints Matches!, but that's not what I want; what I want | is for the test to succeed only for values of 13 or 1. | | Can anybody enlighten me? Yeah. (I hope.) Look at the regular expression you are building: /^13|1$/ This matches anything that starts with a 13, or anything that ends in a 1, of which 101 is clearly an example. What you want instead is: /^(13|1)$/ And, backtracking that into your code: ################################################## $uid_list = "13|1"; $this_uid = 101; if ($this_uid =~ /^($uid_list)$/o) { print "Matches!\n"; } else { print "Doesn't match.\n"; } ################################################## On which I get "Doesn't match.". I wouldn't do it that way, actually. I'd opt first for an assoc array, as in: ################################################## for (13,1) { $cool{$_}++; } if ($cool{101}) { print "Yes!\n"; } else { print "No!\n"; } ################################################## If the values of array are well behaved, I could go for a bitmap, like: ################################################## $cool = ""; for (13,1) { vec($cool,$_,1) = 1; } if (vec($cool,101,1)) { print "Yes!\n"; } else { print "No!\n"; } ################################################## There's More Than One Way To Do It, sez Larry. print pack("h*",unpack("H*","\244W7G\002\026\346\366G\206V'\002\005V'\306\002\206\0266\266V'\302")) -- /=Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ==========\ | on contract to Intel's iWarp project, Beaverton, Oregon, USA, Sol III | | merlyn@iwarp.intel.com ...!any-MX-mailer-like-uunet!iwarp.intel.com!merlyn | \=Cute Quote: "Intel: putting the 'backward' in 'backward compatible'..."====/
rbj@uunet.UU.NET (Root Boy Jim) (02/02/91)
In<5152@s3.ireq.hydro.qc.ca>gamin@ireq-robot.hydro.qc.ca (Martin Boyer) writes: >$uid_list = "13|1"; >$this_uid = 101; >if ($this_uid =~ /^$uid_list$/o) { > print "Matches!\n"; >} else { > print "Doesn't match.\n"; >} > >This section prints Matches!, but that's not what I want; what I want >is for the test to succeed only for values of 13 or 1. You fell into an age old regular expression trap. You just compiled the pattern "^13|1$", which matches 13 at BOL or 1 at EOL. It has nothing to do with numbers, as substitution will show you. You need to compile /^($uid_list)$/o, or put each list member explicitly between ^ and $. >Can anybody enlighten me? No, but at least I can fix your perl problem for you. -- Root Boy Jim Cottrell <rbj@uunet.uu.net> Close the gap of the dark year in between