smackdab has asked for the wisdom of the Perl Monks concerning the following question:

I still think the "c" way ;-)

$_ = "this is an\b correct usage"; my $buff = ''; while (m/(.)/g) { if ($1 eq "\b") { chop($buff) } else { $buff .= $1 } } print $buff;

Replies are listed 'Best First'.
Re: should this backspace removal code be done better?
by BrowserUk (Pope) on Oct 05, 2003 at 05:23 UTC

    Try this

    $s = "this is an\b correct usage"; $s =~ s[.\cH][]g; print $s; this is a correct usage

    Update: Antirice is right, clumbsy.

    $s = "My first attempt was slightly\b\b\b\b\b\b\b\bvery buggy, maybe t +hus\b\bis better?"; $s =~ s[[^\cH]\cH][]g while 1+index $s, chr(8); print $s; My first attempt was very buggy, maybe this better?

    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
    If I understand your problem, I can solve it! Of course, the same can be said for you.

      Small bug:

      #!/usr/bin/perl -wl $s = "this is an\b\b not correct usage"; $s =~ s[.\cH][]g; print $s; print "and one's still there" if grep { ord == ord"\b" } split //,$s; __END__ output: this is not correct usage and one's still there

      It looks correct at first glance, but the second backspace is still there.

      Update: Much better. Only problem is in the case of a leading \b, you can get into an infinite loop. However only the regex needs alteration.

      $s =~ s/(?:[^\cH]\cH|^\cH+)//g while ...

      antirice    
      The first rule of Perl club is - use Perl
      The
      ith rule of Perl club is - follow rule i - 1 for i > 1

        AWESOME, it sinks in slowly ;-)

        This solves the problem from the poster below...
        $s = "\bthis is an\b correct\b\b\b usage\b"; do 1 while ($s =~ s/(?:[^\cH]\cH|^\cH+)//g);

      tr/\b//d would probably be the most efficient form but s/\010//g will also do the job. What is with all the .\010 and while(1)'s in the replies?

      $_ = "hello\b\b\b\b\b\b\hello\b\b"; tr/\b//d; print length($_), $/, $_, $/; __DATA__ 10 hellohello

      cheers

      tachyon

      s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

        You miss the point or I do.

        When you remove the \b, you also have to remove the character behind it over which it backspaced. In your example, the final output should be something like "hel".


        Examine what is said, not who speaks.
        "Efficiency is intelligent laziness." -David Dunham
        "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
        If I understand your problem, I can solve it! Of course, the same can be said for you.

Re: should this backspace removal code be done better?
by eyepopslikeamosquito (Bishop) on Oct 05, 2003 at 06:05 UTC

    If you don't have two backspaces in a row, this quick and dirty will do it:

    $_ = "this is an\b correct usage"; s/.[\b]//g; print;

    Note that \b is a word boundary within a regex but a backspace within a character class.

    For a more correct solution, see the Unix col command or col for PPT. See also Removing characters.

      Make sense, if only you could tell the regex engine to work left to right it would work...I can't assume the user wont hit a backspace twice...I dit it about 6 times typing this reply ;-)
        Out of the mouths of dab'es ! Isn't this a 'sexeger' situation?

        Maybe someone should check my results, 'cuz I can't believe that adding in the reverse's doesn't impact these timings more.   I added a different routine to the mix benchmarked by antirice:

        sub badkcams { $a = reverse $s; $a =~ s[\cH[^\cH]|\cH$][]g while 1+index $a, chr(8); reverse $a; }
        I then ran the benchmark again:
                   Rate    smack     new1       uk badkcams
        smack     191/s       --     -96%     -97%     -97%
        new1     5063/s    2547%       --      -7%     -25%
        uk       5469/s    2759%       8%       --     -19%
        badkcams 6715/s    3411%      33%      23%       --
                   Rate    smack     new1       uk badkcams
        smack    42.4/s       --     -22%     -30%     -44%
        new1     54.7/s      29%       --      -9%     -27%
        uk       60.2/s      42%      10%       --     -20%
        badkcams 75.3/s      78%      38%      25%       --
        
        Am I reading this right?   It's faster?!?
        (This is Perl 5.8.0 AS build 806 running on WinXP.)
Re: should this backspace removal code be done better?
by Roger (Parson) on Oct 05, 2003 at 06:44 UTC
    Yes, you can use the regular expression more efficiently.
    { local $_ = "this is an\b correct usage"; s/(.[\b])//; print "$_\n"; }
    :-)
      Have you even tried it?

      The OP wants to match a backspace, not a backslash followed by a "b"...

      /\b/ doesn't match a backspace, though, but a word boundary. You have to use it in a class to make it match.

      s/.[\b]//g;
Re: should this backspace removal code be done better?
by Roger (Parson) on Oct 05, 2003 at 07:18 UTC
    The regular expression engine can do this for you already! :-)
    local $_ = "this is an\b\b\b correct\b\b\b\b\b\b\b\borrect usage"; s/(.[\b])//; print $_;
    Update: I realized my error and changed \\b to [\b]. Which should now work.

      No, you are replacing backslash followed by 'b' as shown below.

      local $_ = "this \\b is an\b\b\b correct\b\b\b\b\b\b\b\borrect usage"; print "$_\n\n"; s/(.\\b)//g; print $_;

      /-\

Re: should this backspace removal code be done better?
by Aristotle (Chancellor) on Oct 05, 2003 at 17:42 UTC

      A couple of thoughts. First, the 'substr' test code doesn't return the same results as the others.

      I'm also not sure that it makes sense to remove a backspace at the beginning of the line? What would that mean?

      I don't think that it makes too much sense to benchmark strings much beyond a 80 chars or so. Mostly we don't type lines much longer than that, and optimising for the occasional use is pretty pointless. Actually, optimising this whole thing is pretty pointless unless we are going to write programs that simulate a person typing including their typos and corrections:) Even the slowest version is way faster than (I) can type a line of input.

      Finally, if the optimisation is just for fun, a way to while away a boring Sunday afternoon, here's a version that does pretty well on the short tests, but comes in second on the longer strings.


      Examine what is said, not who speaks.
      "Efficiency is intelligent laziness." -David Dunham
      "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
      If I understand your problem, I can solve it! Of course, the same can be said for you.