Hello Melly,
I see you’ve been given detailed explanations of the first snippet, which uses the transliteration operator tr///, but not of the second, which uses the substitution operator s///:
my $count = length( $str =~ s/[^\Q$char\E]//rg );
There is actually quite a bit of detail to unpack here. The effect of the code is to create a string from which all non-$char characters have been removed, and then count the remaining characters in that string (i.e., just the $char characters). Removal of the non-$char characters is accomplished by replacing them with the empty string in the replacement part of the substitution.
- The /g modifier causes the substitution to be performed globally, i.e., repeatedly throughout the string. See https://perldoc.perl.org/perlre#Modifiers.
- The /r modifier causes the substitution to be performed on a new string, which is returned, leaving the original string unchanged. See the same reference.
- The square brackets create a character class, on which see https://perldoc.perl.org/perlrecharclass#Bracketed-Character-Classes.
- Within the character class, the initial ^ (caret) character negates the class, meaning it now matches any characters except those specified. See https://perldoc.perl.org/perlrecharclass#Negation.
- The \Q escape sequence removes the special meaning from any metacharacters following it. For example, if $char has the value "]" (right square bracket) and is not escaped, the compiler will see it as the end-delimiter of the character class. The \Q ensures that the compiler sees it as merely the character "]". See https://perldoc.perl.org/perlre#Escape-sequences.
- The \E escape sequence restores their normal meaning to any metacharacters that follow. See the same reference.
- length is the built-in Perl function which returns the number of characters in a string.
Hope that helps,