╔╦╗╦ ╦╔═╗ ╦╔═╗╔═╗╦ ╦ ╔╦╗╦═╗╔═╗╔╦╗╦╔╦╗╦╔═╗╔╗╔ ║ ╠═╣║╣ ║╠═╣╠═╝╠═╣ ║ ╠╦╝╠═╣ ║║║ ║ ║║ ║║║║ ╩ ╩ ╩╚═╝ ╚╝╩ ╩╩ ╩ ╩ ╩ ╩╚═╩ ╩═╩╝╩ ╩ ╩╚═╝╝╚╝ ============================================================================ THE ONE-LINER print'4A75737420616E6F74686572205065726C206861636B6572' =~s~.{2}~"qq(\\x{$&})"~regex; Looks like someone sneezed on a keyboard, right? But run it and you get: Just another Perl hacker Let's crack this thing open. ============================================================================ PART 1: THE HEX BLOB -------------------- 4A75737420616E6F74686572205065726C206861636B6572 That's not random garbage. It's hex-encoded ASCII. 4A = J 75 = u 73 = s 74 = t 20 = (space) ...and so on Every two characters represent one letter. The whole blob spells out "Just another Perl hacker" but encoded so you can't just read it. Quick way to verify in Perl: perl -e 'print pack("H*", "4A757374")' # outputs: Just ============================================================================ PART 2: THE TILDE DELIMITERS ---------------------------- Normal regex uses slashes: s/old/new/ But Perl lets you use almost any character as a delimiter. We use tildes: s~old~new~ Why? Our replacement string has slashes and quotes in it. Tildes keep things clean. No escaping nightmare. Also looks cooler. Fight me. ============================================================================ PART 3: THE PATTERN ------------------- .{2} Dead simple. Match any two characters. That's it. . = any character {2} = exactly two of them So we're grabbing the hex blob two characters at a time: 4A, 75, 73, 74, 20, 61, 6E, 6F... Each pair becomes one letter after we transform it. ============================================================================ PART 4: THE REPLACEMENT STRING ------------------------------ Here's where it gets spicy: "qq(\\x{$&})" Let's unpack this onion. $& is a special variable. It holds whatever the regex just matched. So when we match "4A", $& contains "4A". The replacement builds a string that looks like: qq(\x{4A}) That double backslash (\\) becomes a single backslash in the output. So after the FIRST eval pass, we have: qq(\x{4A}) Which is valid Perl code. A qq() string containing a hex escape. ============================================================================ PART 5: THE MODIFIERS (THE REAL TRICK) -------------------------------------- ~regex Look at those modifiers. Now look again. r - e - g - e - x They spell "regex". While being regex modifiers. In a regex. .--. |o_o | |:_/ | // \ \ (| | ) /'\_ _/`\ \___)=(___/ Your brain should hurt a little. That's normal. But here's what they actually DO: r = Return the result (don't modify original string) e = Evaluate replacement as Perl code g = Global (do it for every match, not just the first) e = Evaluate AGAIN (the second e, hidden in "regex") x = Extended mode (allows whitespace in pattern - unused here) The x is just along for the ride. It's there to spell the word. ============================================================================ PART 6: THE DOUBLE EVAL (ee) ---------------------------- This is the actual sorcery. Most people miss it. See those two e's in "regex"? That's "ee" - double eval. Here's how it flows for the hex pair "4A": MATCH: "4A" FIRST e (eval): Evaluates "qq(\\x{$&})" as code $& is "4A" Result: the STRING qq(\x{4A}) SECOND e (eval again): Evaluates qq(\x{4A}) as code Perl sees \x{4A} inside quotes Interprets it as hex escape Result: "J" OUTPUT: J One e would just give you the literal text "qq(\x{4A})". Two e's actually runs it and converts the hex. ============================================================================ PART 7: PUTTING IT ALL TOGETHER ------------------------------- print'4A75737420616E6F74686572205065726C206861636B6572' =~s~.{2}~"qq(\\x{$&})"~regex; Step by step: 1. Start with hex blob 2. Match every two characters 3. For each pair, build qq(\x{XX}) 4. First eval creates the qq() string 5. Second eval interprets the \x{} escape 6. r modifier returns the transformed string 7. print sends it to screen Output: Just another Perl hacker ============================================================================ WHY "regex" INSTEAD OF "geer"? ------------------------------ The normal way to write this would be: s~.{2}~"qq(\\x{$&})"~geer Same result. But where's the fun in that? Spelling "regex" with the modifiers is the whole point. It's self-referential humor. The modifiers describe what they are. It's a JAPH - it's supposed to make you smile when you figure it out. The x modifier does nothing useful here. It's just completing the word. That's the joke. ============================================================================ TRY IT YOURSELF --------------- Save this as japh.pl and run it: #!/usr/bin/perl print'4A75737420616E6F74686572205065726C206861636B6572' =~s~.{2}~"qq(\\x{$&})"~regex; Or one-liner it: perl -e 'print q{4A7573742061}=~s~.{2}~"qq(\\x{$&})"~regex' (shortened hex for readability - try the full blob yourself) ============================================================================ HOMEWORK: ENCODE YOUR OWN ------------------------- Want to make your own message? Here's how to get the hex: perl -e 'print unpack("H*", "Your message here")' Then wrap it in the same pattern. Welcome to the club. ============================================================================ _____ / \ | () () | \ ^ / ||||| ||||| "Now you know. And knowing is half the battle." - Some 80s cartoon, probably ============================================================================ japh.codes