in reply to Re: Re: Search and replace in an array using data in hash
in thread Search and replace in an array using data in hash

Well, yes, there was viel magisches in that one line. Let's pull it apart.

Because you said there could be more than one IP address per line Abigail-II, halley and Zaxo all understood they needed to find just IP addresses, maybe more than one, and then _maybe_ substitute a name. So they said:

s/ <IP address pattern> / <magic> / g
using the 'g' to match as many times as needed and using a special pattern to match only things that looked like IP addresses.

For the special pattern Zaxo just said '$ipre' because there are a lot of REs you could use to match IP addresses. Abigail-II suggested you use the Regexp::Common module which has a predefined RE for that.

So s///g will find each IP address in a line, save that matched string in $1, and then do the second part, the substitution. But we want to lookup the string and replace it only if it is _found_ in your hash.

If you use the 'e' modifier on a s/// you are saying the second substitute part has _code_ in it. You can make decisions about exactly what to substitute. Zaxo used

( exists($hosts{$1}) ? $hosts{$1} : $1 )
to make the decision very clear. He said that if the matched IP address (saved in $1) could be found in your hash (something existed in %hosts with the key $1) then we want to substitute the value in $hosts{$1}, otherwise we just want to use the original matched string (we don't have anything to substitute).

What halley used was a shortcut way of saying the same thing:

$hash{$1} || $1
The || 'or' operator will use the first value if it is not false otherwise it will use the second value. If you try to lookup a value using a key when you haven't stored something in the hash using that key, Perl doesn't die but rather quietly says "I don't have anything here for that key." The value returned by $hash{'unbekannt'} is simply the 'undef' value. 'undef' is false so the above expression will throw away the first value and use the second value. So if the IP address is found in the hash we use '$hash{$1}' otherwise we use '$1'.