http://www.perlmonks.org?node_id=1016594

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

Hello monks,
I'm trying to understand what the following regex does,


 print s/$temp1/$words{$temp1} ? "$temp " : "[$temp]"/ex;

I expected it to return the result of the ternary operator, but instead it's returning the value of a hash?

$temp is a string, $temp1 is the same string but entirely lowercase, and %words is populated (word => 1, word2 => 1, word3 =>1 ...).

Thank you!

EDIT 22:26
Using toolic's suggestion I fixed it by setting it as follows:

for my $temp (@line) { $_ = lc($temp); s/$_/$words{$_} ? "$temp " : "[$temp] "/ex; print; }

Where @line contains all the words in a line of input.
J -

Replies are listed 'Best First'.
Re: help with a regex
by toolic (Bishop) on Feb 01, 2013 at 18:16 UTC
    You are printing the return value of s///, which is the number of substitutions made. If there was only 1 substitution, it prints 1, which just happens to match the hash value. You should print $_ instead:
    use warnings; use strict; my %words = (word => 1, word2 => 1, word3 =>1); my $temp = 'WORD2'; my $temp1 = 'word2'; $_ = 'here is word2'; s/$temp1/$words{$temp1} ? "$temp " : "[$temp] "/ex; print "$_\n"; __END__ here is WORD2
      You should print $_ instead

      Or, just add the /r modifier to the substitution:

      #! perl use v5.14; use warnings; use strict; my %words = (word => 1, word2 => 1, word3 => 1); my ($temp, $temp1) = qw(WORD2 word2); $_ = 'here is word2'; say s/$temp1/$words{$temp1} ? "$temp " : "[$temp] "/er;

      Output:

      13:14 >perl 515_SoPW.pl here is WORD2 13:15 >

      From s/PATTERN/REPLACEMENT/msixpodualgcer in Regexp Quote Like Operators:

      r Return substitution and leave the original string untouched.

      Hope that helps,

      Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

        It should be made clear that the  s///r regex switch is only available with Perl versions 5.14 and above.

Re: help with a regex
by 7stud (Deacon) on Feb 01, 2013 at 18:52 UTC

    From perlop:

    s/PATTERN/REPLACEMENT/msixpodualgcer

    Searches a string for a pattern, and if found, replaces that pattern with the replacement text and returns the number of substitutions made. Otherwise it returns false (specifically, the empty string).

    All function calls in your code are replaced by their return values. Your code is essentially this:

    print do_stuff();

    When perl encounters the function call do_stuff(), perl halts execution of the print statement, then perl executes the function do_stuff(), then perl replaces the call to do_stuff() in your code with do_stuff()'s return value.

    You could do this:

    use strict; use warnings; use 5.012; my $target = 'hello'; my %should_replace = ('hello' => 1); my $repl = 'Hello'; $_ = 'hello world goodbye'; s/$target/print $should_replace{$target} ? "$repl " : "[$repl] "/ex;

    ...but that's pretty ugly. I think the following are better alternatives:

    use strict; use warnings; use 5.012; my $text = 'hello world goodbye'; my $target = 'hello'; my %should_replace = ('hello' => undef); my $repl = 'Hello'; if ($text =~ $target) { my $output = exists $should_replace{$target} ? "$repl " : "[$repl] + "; say $output; }
    use strict; use warnings; use 5.012; my $text = 'hello world goodbye'; my $target = 'hello'; my %keys = ('world' => undef); my $repl = 'Hello'; if ($text =~ $target) { my $output; if (exists $keys{$target}) { $output = $repl; } else { $output = "[$repl]"; } say "$output "; } --output:-- [Hello]

    The goal is code clarity--not cramming as much code into one line as possible.

    Is there a reason you aren't putting the replacement text in the hash?