Prev: unintialised warning
Next: optimizar r/w en ficheros
From: Paul Lalli on 2 Nov 2009 14:07 A coworker just presented me with this task. I came up with two solutions, but I don't like either of them. He has a text document and wants to scan it for characters such as newline, tab, form feed, carriage return, vertical tab. If found, he wants to replace them with their typical representation (ie, \n, \t, \f, \r, \v). I first gave him the obvious: $string =~ s/\n/\\n/; $string =~ s/\t/\\t/; $string =~ s/\f/\\f/; $string =~ s/\r/\\r/; $string =~ s/\v/\\v/; which I don't like because of how much copy/paste is involved. Then I came up with: for (qw/n t f r v/) { my $meta = eval("\\$_"); $string =~ s/$meta/\\$_/; } which I don't like, because the comment he'd have to put in the code to explain it would be longer than the code itself, or the first version. So can anyone think of a better way? Is there any kind of intrinsic link between a newline character and the letter 'n' that could be used to go "backwards" here? Thanks, Paul Lalli
From: Uri Guttman on 2 Nov 2009 14:40 >>>>> "PL" == Paul Lalli <mritty(a)gmail.com> writes: PL> A coworker just presented me with this task. I came up with two PL> solutions, but I don't like either of them. He has a text document PL> and wants to scan it for characters such as newline, tab, form feed, PL> carriage return, vertical tab. If found, he wants to replace them PL> with their typical representation (ie, \n, \t, \f, \r, \v). PL> I first gave him the obvious: PL> $string =~ s/\n/\\n/; PL> $string =~ s/\t/\\t/; PL> $string =~ s/\f/\\f/; PL> $string =~ s/\r/\\r/; PL> $string =~ s/\v/\\v/; PL> which I don't like because of how much copy/paste is involved. Then I PL> came up with: use a hash table for the conversion: my %controls = ( "\n" => '\\n', "\t" => '\\t', "\r" => '\\r', "\f" => '\\f', "\v" => '\\v', ) ; $string =~ s/([\n\t\r\f\v])/$controls{$1}/g; and if you want to get anal about dups of the chars do this: my @controls = qw( n t r f v ) ; my %control_to_escape = map { eval( "\\$_" ) => "\\$_" } @controls ; my $controls_re = '[' . join( '', map "\\$_", @controls ) . ']' ; $string =~ s/($controls_re)/$controls_to_escape{$1}/g; see ma! only one use of the actual control letters! uri -- Uri Guttman ------ uri(a)stemsystems.com -------- http://www.sysarch.com -- ----- Perl Code Review , Architecture, Development, Training, Support ------ --------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
From: sln on 2 Nov 2009 15:21 On Mon, 2 Nov 2009 11:07:56 -0800 (PST), Paul Lalli <mritty(a)gmail.com> wrote: >A coworker just presented me with this task. I came up with two >solutions, but I don't like either of them. He has a text document >and wants to scan it for characters such as newline, tab, form feed, >carriage return, vertical tab. If found, he wants to replace them >with their typical representation (ie, \n, \t, \f, \r, \v). > >I first gave him the obvious: >$string =~ s/\n/\\n/; >$string =~ s/\t/\\t/; >$string =~ s/\f/\\f/; >$string =~ s/\r/\\r/; >$string =~ s/\v/\\v/; > >which I don't like because of how much copy/paste is involved. Then I >came up with: > >for (qw/n t f r v/) { > my $meta = eval("\\$_"); > $string =~ s/$meta/\\$_/; >} > >which I don't like, because the comment he'd have to put in the code >to explain it would be longer than the code itself, or the first >version. > >So can anyone think of a better way? Is there any kind of intrinsic >link between a newline character and the letter 'n' that could be used >to go "backwards" here? > Yet another way.. use strict; use warnings; my %translation = ( '\n'=>"\n", '\t'=>"\t", '\f'=>"\f", '\r'=>"\r", # ,'\v'=>"\v" - no 'v' for 'm'e, vt? ); my $sample = "line 1\tsome\nline 2\t\t\f\n\rline 3\n"; while (my ($literal,$actual) = each %translation) { $sample =~ s/$actual/$literal/eg; } print $sample; __END__ -sln
From: Randal L. Schwartz on 2 Nov 2009 15:11 >>>>> "Uri" == Uri Guttman <uri(a)StemSystems.com> writes: >>>>> "PL" == Paul Lalli <mritty(a)gmail.com> writes: PL> A coworker just presented me with this task. I came up with two PL> solutions, but I don't like either of them. He has a text document PL> and wants to scan it for characters such as newline, tab, form feed, PL> carriage return, vertical tab. If found, he wants to replace them PL> with their typical representation (ie, \n, \t, \f, \r, \v). PL> I first gave him the obvious: PL> $string =~ s/\n/\\n/; PL> $string =~ s/\t/\\t/; PL> $string =~ s/\f/\\f/; PL> $string =~ s/\r/\\r/; PL> $string =~ s/\v/\\v/; PL> which I don't like because of how much copy/paste is involved. Then I PL> came up with: Uri> use a hash table for the conversion: Uri> my %controls = ( Uri> "\n" => '\\n', Uri> "\t" => '\\t', Uri> "\r" => '\\r', Uri> "\f" => '\\f', Uri> "\v" => '\\v', Uri> ) ; Just to scare people: my %controls = ( "\n" => '\n', "\t" => '\t', "\r" => '\r', "\f" => '\f', "\v" => '\v', ); Ok, that's downright evil. :) print "Just another Perl hacker,"; # the original -- Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095 <merlyn(a)stonehenge.com> <URL:http://www.stonehenge.com/merlyn/> Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc. See http://methodsandmessages.vox.com/ for Smalltalk and Seaside discussion
From: sln on 2 Nov 2009 15:26
On Mon, 02 Nov 2009 12:21:06 -0800, sln(a)netherlands.com wrote: >On Mon, 2 Nov 2009 11:07:56 -0800 (PST), Paul Lalli <mritty(a)gmail.com> wrote: > >while (my ($literal,$actual) = each %translation) { > $sample =~ s/$actual/$literal/eg; $sample =~ s/$actual/$literal/g; -sln |