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

Hi,
How could I remove one or more character at certain position in the string ? ...

As example :
123456789 ==> 12345689
ABCDEFGHI ==> ABCEFGHI
223344556 ==> 2244556

TQ,

  • Comment on How to remove character at certain position in the String.....

Replies are listed 'Best First'.
Re: How to remove character at certain position in the String.....
by jweed (Chaplain) on Dec 02, 2003 at 08:57 UTC
    substr. As an lvalue. With undef. Or with undef as the fourth argument.


    Who is Kayser Söze?
    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: How to remove character at certain position in the String.....
by l3nz (Friar) on Dec 02, 2003 at 09:35 UTC
    I'd probably do it with substr, usually, but you can do it using a regexp too. As the regexp does not match if you do not have enough chars, you do not have to worry about malformed strings (you only 'touch' strings that are meaningful).

    This is a sample:

    use strict; my $a; my $from = 2; my $len = 2; while( $a = <DATA> ) { chomp $a; print "Before: '$a' "; $a = $1 . $2 if $a =~ /^(.{$from}).{$len}(.*)$/i; print "After '$a'\n"; } __DATA__ 12345678 yellow a xx yyy
      I would use qr// to compile the regex before the loop so you don't have the (potentially) large overhead each iteration.

      Update

      I am wrong. Do not listen to me.



      Who is Kayser Söze?
        What potential overhead? Perl will *not* recompile the regex in each iteration (unless you modify $from or $len). Here's a proof, assuming the program is in the file /tmp/qq:
        $ perl -Dr /tmp/qq 2>&1 | grep Compiling Compiling REx `^(.{2}).{2}(.*)$' $
        It only gets compiled once.

        Here's a benchmark:

        #!/usr/bin/perl use strict; use warnings; use Benchmark 'cmpthese'; our @data = <DATA>; chomp @data; our $from = 2; our $len = 2; our (@a, @b, @c); cmpthese -10 => { substr => 'for (@a = @data) { substr $_, $from, $len, "" if length ($_) >= $fro +m + $len }', regex => 'for (@b = @data) { $_ = $1 . $2 if /^(.{$from}).{$len}(.*)$/; }', regex_qr => 'my $qr = qr /^(.{$from}).{$len}(.*)$/; for (@c = @data) { $_ = $1 . $2 if /$qr/; }', }; die "Unequal" unless "@a" eq "@b" && "@b" eq "@c"; __DATA__ 12345678 yellow a xx yyy a somewhat longer line to compensate for the smaller lines. bla bla bla bla Rate regex_qr regex substr regex_qr 38207/s -- -3% -62% regex 39497/s 3% -- -60% substr 99555/s 161% 152% --

        Abigail