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

I am trying to analyze someone else's code and understand what it does. One small block in particular is confusing me:
if($data !~ /^[\ -\~\007\012\015\035\036\037]*$/) { $data =~ tr/[\ -\~\007\012\015\035\036\037]/ /cs; }

For purposes of testing, $data is set to a "string" of the entire ASCII table (0-255) appended together.

I expect that if the first regex (in the if) finds any character that is not in the regex, the expression evaluates to true and it enters the block. If $data consists entirely of those special characters, the expression will evaluate false.

Once in the block, the tr///cs is where my confusion lies. In the Camel book, it says that /c causes the SEARCHLIST character set to be complemented. I expect this to mean that the SEARCHLIST will now match any character that is NOT included in the list. However, the output of $data is:

&#8596;&#9650;&#9660; !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNO +PQRSTUVWXYZ[\]^_`abcdefghijk lmnopqrstuvwxyz{|}~
This is considerably more than what I expect to see. Can anyone explain this bit of code to me?

Replies are listed 'Best First'.
Re: tr///c doesn't seem to work as I expect
by almut (Canon) on Sep 04, 2009 at 20:33 UTC

    Have you, maybe, overlooked the range " " (space) to "~" in the pattern?

      Wow.. maybe. Is that a valid range? I thought it meant '-' itself. That must be it.
        From perlop:
        The character "-" is treated specially and therefore "\-" is treated +as a literal "-".

        The - indicates a range.

        if($data !~ /^[\ \-\~\007\012\015\035\036\037]*$/) { $data =~ tr/[\ \-\~\007\012\015\035\036\037]/ /cs; }
        is probably what you need.