| Bytes | Lang | Time | Link |
|---|---|---|---|
| 061 | Perl 5 nl | 241018T170320Z | Xcali |
| 024 | Uiua | 241019T021902Z | nyxbird |
| nan | Perl | 161207T154018Z | Gabriel |
| 058 | Ruby | 160413T212212Z | Value In |
Perl, 80 + 1 = 81 bytes
Run with the -p flag
$a=join"(.*?)",split//,<>;$b.=$_." .\$".++$;."."for split//,<>;chop$b;s/$a/$b/ee
The code procedurally generates a search and replace regex command, which it then executes in the last bit of code.
The string ghost in the first example gets turned into the string g(.*?)h(.*?)o(.*?)s(.*?)t(.*?), which means a g followed by 0 or more characters, followed by an h followed by 0 or more characters, followed by etc. The *? quantifier means that the search should be non-greedy and "gobble" as few characters as possible, instead of the default of matching as much as possible.
The string 12345 then gets turned into 1 .$1.2 .$2.3 .$3.4 .$4.5 .$5, which gets evaluated after the regex is performed. Each of $1,$2,$3,$4,$5 is actually a backreference to a capture group (in parentheses) from the first string.
Ruby, 70 64 59 58 bytes
Anonymous function. Walk through the string a to build a new string with letters replaced in accordance to the next character in b and c, then if all characters in b are exhausted at the end, return the newly constructed string, otherwise return the original string.
@histocrat helped save 6 bytes via gsub.
Saved 1 byte thanks to @Cyoce.
->a,b,c{i=0;s=a.gsub(/./){$&==b[i]?c[~-i+=1]:$&};b[i]?a:s}