himanshu.padmanabhi has asked for the wisdom of the Perl Monks concerning the following question:

I want to remove ^@ from the end,only if it gets appended to $str.
$str="himanshu.txt^@"; if($str =~ /(\w+)/) { $str = "$1.$2"; }
This is working well.So I am getting $str="himanshu.txt" Now second case.If I am having cases like $str="himanshu-prg.txt^@" or $str="hel_llo-workd.txt^@"What will the regular expression? CONCLUSION possible patterns; $str= <combination of words,number,dash> . txt (somtimes ^@ gets appended,so i want to sense that and remove)

Replies are listed 'Best First'.
Re: pattern matching
by toolic (Bishop) on Mar 04, 2009 at 14:58 UTC
    To remove trailing "^@", you could use the substitution operator:
    use strict; use warnings; while (my $str = <DATA>) { chomp $str; $str =~ s/\^\@$//; print "$str\n"; } __DATA__ himanshu.txt^@ himanshu-prg.txt^@ hel_llo-workd.txt^@ foo

    prints:

    himanshu.txt himanshu-prg.txt hel_llo-workd.txt foo
      Probably he wants =~ s/[^\w.]*$//; because
      $ perl -le print(chr(0)) |cat -v ^@
Re: pattern matching
by shmem (Chancellor) on Mar 04, 2009 at 15:44 UTC

    That should be

    $str="himanshu.txt^@"; if($str =~ /(\w+)\.(\w+)/) { $str = "$1.$2"; }

    What is your "^@" ? That looks like an ASCII 0, as less(1) would show it. You can sense that and remove it with

    if ($str =~ s/\0$//) { print "found NUL byte at the end of '$str'\n"; }
Re: pattern matching
by cdarke (Prior) on Mar 04, 2009 at 14:56 UTC
    TMTOWTDI: you could use chomp instead:
    { local $/ = "^@"; chomp $str; }
      Thank you very much. You already given me this solution. It is working well. I should have try it that time only.:(
Re: pattern matching
by AnomalousMonk (Archbishop) on Mar 04, 2009 at 15:22 UTC
    What is "^@"? If it is a Control-@ (ASCII null) character, then
        $string =~ s{ \c@ \z }{}xms;
    will do the trick. If there may be more than one, use
        $string =~ s{ \c@ + \z }{}xms;
    >perl -wMstrict -le "my $string = qq{ab.cd\c@}; print qq{'$string'}; $string =~ s{ \c@ \z }{}xms; print qq{'$string'}; " 'ab.cd ' 'ab.cd' >perl -wMstrict -le "my $string = qq{ab.cd\c@\c@\c@}; print qq{'$string'}; $string =~ s{ \c@ + \z }{}xms; print qq{'$string'}; " 'ab.cd ' 'ab.cd'
Re: pattern matching
by GrandFather (Saint) on Mar 04, 2009 at 22:23 UTC

    Always use strictures (use strict; use warnings;). That code should have generated the warning:

    Use of uninitialized value in concatenation (.) or string at ...

    True laziness is hard work
Re: pattern matching
by Anonymous Monk on Mar 04, 2009 at 14:50 UTC
    This is working well.So I am getting $str="himanshu.txt"

    Not possible, $2 is always undefined.

    #!/usr/bin/perl -- use strict; use warnings; my $str="himanshu.txt^@"; if($str =~ /(\w+)/) { $str = "$1.$2"; } print "$str\n" __END__ Use of uninitialized value in concatenation (.) or string at - line 6. himanshu.
    What will the regular expression?
    use re 'debug'; to see, ex
    #!/usr/bin/perl -- use strict; use warnings; use re 'debug'; my $str="himanshu.txt^@"; if($str =~ /(\w+)/) { $str = "$1.$2"; } print "$str\n" __END__ Compiling REx `(\w+)' size 7 Got 60 bytes for offset annotations. first at 4 1: OPEN1(3) 3: PLUS(5) 4: ALNUM(0) 5: CLOSE1(7) 7: END(0) stclass "ALNUM" plus minlen 1 Offsets: [7] 1[1] 0[0] 4[1] 2[2] 5[1] 0[0] 6[0] Matching REx "(\w+)" against "himanshu.txt^@" Matching stclass "ALNUM" against "himanshu.txt^@" Setting an EVAL scope, savestack=5 0 <> <himanshu.txt> | 1: OPEN1 0 <> <himanshu.txt> | 3: PLUS ALNUM can match 8 times out of 2147483647.. +. Setting an EVAL scope, savestack=5 8 <manshu> <.txt^@> | 5: CLOSE1 8 <manshu> <.txt^@> | 7: END Match successful! Use of uninitialized value in concatenation (.) or string at test.pl l +ine 7. himanshu. Freeing REx: `"(\\w+)"'