Rob, can you explain the details of that replace? That's pretty slick. I see you're adding the hex value to get to the appropriate ASCII value, but didn't know you could do some of that gyration inside a regex.
Thanks. -Tom Kinzer -----Original Message----- From: Rob Dixon [mailto:[EMAIL PROTECTED] Sent: Tuesday, December 09, 2003 11:58 AM To: [EMAIL PROTECTED] Subject: Re: Pattern Match Eric Sand wrote: > > I am very new to Perl, but I sense a great adventure ahead after just > programming with Cobol, Pascal, and C over the last umpteen years. I have > written a perl script where I am trying to detect a non-printing > character(Ctrl@ - Ctrl_) and then substitute a printing ASCII sequence such > as "^@" in its place, but it does not seem to work as I would like. Any > advice would be greatly appreciated. > > Thank You....Eric Sand > > Your obvious guess is to write Perl as if it were C. That's slightly better than treating it as a scripting language, but there are many joys left to be found! > $in_ctr=0; > $out_ctr=0; > > while ($line = <STDIN>) > { > chomp($line); > $in_ctr ++; > if ($line = s/\c@,\cA,\cB,\cC,\cD,\cE,\cF,\cG,\cH,\cI,\cJ,\cK, > \cL,\cM,\cN,\cO,\cP,\cQ,\cR,\cS,\cT,\cU,\cV,\cW, > \cX,\cY,\cZ,\c[,\c\,\c],\c^,\c_ > /^@,^A,^B,^C,^D,^E,^F,^G,^H,^I,^J,^K, > ^L,^N,^N,^O,^P,^Q,^R,^S,^T,^U,^V,^W, > ^X,^Y,^Z,^[,^\,^],^^,^_/) > { > $out_ctr ++; > printf("Non-printing chars detected in: %s\n",$line); > } > } > printf("Total records read = %d\n",$in_ctr); > printf("Total records written with non-printing characters = %d\n",$out_ctr); I would write this as below. The first things is to *always* use strict; use warnings; after which you have to declare all of your variables with 'my'. The second is to get used to using the default $_ variable which is set to the value for the current 'while(<>)' or 'for' loop iteration, and is a default parameter for most built-in functions. Finally, in your particular case you're using the s/// (substitute) operator wrongly. The first part, s/here//, is a regular expression, not a list of characters. You'll need to read up on these at perldoc perlre The second part, s//here/, is a string expression which can use 'captured' sequences (anything in brackets) from the first part and, with the addition of the s///e (executable) qualifier can also be an executable statement. Here I've used it to add 0x20 to the ASCII value of the control character grabbed by the regex. A lot of this won't make sense until you learn some more, but I hope you'll agree that this code is cuter than your original? HTH, Rob use strict; use warnings; my $in_ctr = 0; my $out_ctr = 0; while (<>) { chomp; $in_ctr++; if (s/([\x00-\1F])/'^'.chr(ord($1) + 0x40)/eg) { $out_ctr++; printf "Non-printing chars detected in: %s\n", $_; } } printf "Total records read = %d\n", $in_ctr; printf "Total records written with non-printing characters = %d\n", $out_ctr; -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] <http://learn.perl.org/> <http://learn.perl.org/first-response> -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] <http://learn.perl.org/> <http://learn.perl.org/first-response>