Path: utzoo!news-server.csri.toronto.edu!cs.utexas.edu!swrinde!elroy.jpl.nasa.gov!jpl-devvax!lwall From: lwall@jpl-devvax.jpl.nasa.gov (Larry Wall) Newsgroups: comp.lang.perl Subject: Re: Can this be done more slickly Message-ID: <1991Mar16.025628.2227@jpl-devvax.jpl.nasa.gov> Date: 16 Mar 91 02:56:28 GMT References: Reply-To: lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) Distribution: comp Organization: Jet Propulsion Laboratory, Pasadena, CA Lines: 62 In article victor@ibm.com writes: : I wrote the function given below to transform a string with -'s in it : so that all alphabetics were lower case, except at the beginning of : the string or immediately after a dash, in which case it would be : upper case. The follow works correctly, but I was wondering (in the : JAPH spirit), if there is a more clever (or concise) way of doing it. : : sub normalize { : local(@pieces) = split(/-/,$_[0]); : local($i); : foreach $i (0..$#pieces) { : $pieces[$i] =~ tr/A-Z/a-z/; : substr($pieces[$i],0,1) =~ tr/a-z/A-Z/; : } : join('-',@pieces); : } Oh, there's probably several things we can do to improve it. First, you don't need to use an index: sub normalize { local(@pieces) = split(/-/,$_[0]); foreach $piece (@pieces) { $piece =~ tr/A-Z/a-z/; substr($piece,0,1) =~ tr/a-z/A-Z/; } join('-',@pieces); } You could get a little more concise with a substitute instead of a split: sub normalize { local($_) = @_; local($tmp); tr/A-Z/a-z/; s#((^|-)[a-z])#($tmp = $2) =~ tr/A-Z/a-z/,$tmp#eg; $_; } That's still a bit gross. With 4.0, you'll be able to do it like this: sub normalize { local(@pieces) = split(/-/,$_[0]); foreach $piece (@pieces) { $piece = "\u\L$piece"; } join('-',@pieces); } or sub normalize { local($_) = "\u\L$_[0]"; s/-([a-z])/-\u$1/g; $_; } or, for those who prefer one-liners, sub normalize { join('-', grep(s/(.*)/\u\L$1/, split(/-/, $_[0]))); } Larry