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

$A =~ tr[\n][]d;

In this what is the meaning of =~ tr[\n][]d;

Replies are listed 'Best First'.
Re: Meaning of command
by davido (Cardinal) on Jul 10, 2014 at 04:21 UTC

    The transliteration operator; tr/// is discussed in perlop, as is the binding operator (=~).

    The code you posted will remove all newlines from the string contained in $A.


    Dave

Re: Meaning of command
by boftx (Deacon) on Jul 10, 2014 at 05:10 UTC

    From the perldoc:

    tr/SEARCHLIST/REPLACEMENTLIST/cdsr y/SEARCHLIST/REPLACEMENTLIST/cdsr ... Options: c Complement the SEARCHLIST. d Delete found but unreplaced characters. s Squash duplicate replaced characters. r Return the modified string and leave the original string untouched. If the /c modifier is specified, the SEARCHLIST character set is compl +emented. If the /d modifier is specified, any characters specified by SEARCHLIS +T not found in REPLACEMENTLIST are deleted. (Note that this is slightly more + flexible than the behavior of some tr programs, which delete anything they find + in the SEARCHLIST, period.) If the /s modifier is specified, sequences of cha +racters that were transliterated to the same character are squashed down to a +single instance of the character. If the /d modifier is used, the REPLACEMENTLIST is always interpreted +exactly as specified.
    "\n"s are being deleted because they are not specified in the replacement list.

    NOTE! the /r option is relatively new and may not be present in your version of Perl. Check your local docs to be sure.

    You must always remember that the primary goal is to drain the swamp even when you are hip-deep in alligators.
Re: Meaning of command
by lidden (Curate) on Jul 10, 2014 at 04:16 UTC
    It is removing all new line characters from the string.

    Also you should put code tags around code: <code> ... </code>.

Re: Meaning of command
by Anonymous Monk on Jul 10, 2014 at 04:01 UTC
Re: Meaning of command
by Bethany (Scribe) on Jul 10, 2014 at 20:35 UTC

    This info might be useful to a beginner. If you aren't used to Perl's way of doing things, the square brackets in $A =~ tr[\n][]d; can look confusingly like array subscripting or references to an anonymous list. Regex operators can be tricky because you get to pick the delimiter. This tripped me up a few times when I was new to Perl.

    While reading up on regex operations, pay special attention to how delimiters are chosen. The slash character / is conventionally used in documentation and examples, but you can choose some other non-whitespace character -- or a matching pair of "bracketing" characters, such as [ and ] in your example, or ( and ), et cetera.

    Whichever delimiter(s) you choose, if that character or characters has special meaning within regular expressions, and you need to use the character's special meaning as well as its literal value, you'll have to backslash-escape it or them.

    For instance, when using [ and ] as delimiters for an expression, within that expression you won't be able to use the square brackets as regex character-set operators unless you escape them with a backslashes. In other words, where you might use /[a-zA-Z][0-9]+/ to match a letter followed by one or more digits, if you choose to use square brackets instead of slashes you'll need to write [\[a-ZA-Z\]\[0-9\]+].

    You can see square brackets would be a poor choice of delimiters for that particular regex, since escaping adds "noise" characters that obscure the meaning of the regex. The usual forward slash delimiters, as in the original /[a-zA-Z][0-9]+/, make it easier to tell what the regex does. Since there are no literal slashes in the regex, there's no reason to avoid using / as the delimiter.

    However, if you were matching parts of a path or of a URL, either of which is likely to contain slashes as literal characters to match against, square brackets might make sense. Suppose I have a variable containing a path, such as $path_with_fname = "/home/bethany/images/lolcat.gif", and I want to separate the path itself and the filename. I could match fname against [(.*)/(.*?)]. This is less "noisy" than writing /(.*)\/(.*?)/, where the literal slash in the middle must be backslash-escaped.

    In other words, try to choose a delimiter character or characters that you won't be using as a literal character within the regex.

    I hope this wasn't too confusing, too detailed, or both. Experiment with a throw-away script and various patterns and you'll get the hang of it soon enough.

    (edited 'cos typos and grammatical errors will sneak in even when you preview)