Case Matching Find Replace Take three inputs, a string of text, T; a string of characters to replace, F; and a string of characters to replace them with, R. For each substring of T with the same (case insensitive) characters as F, replace them with the characters in R. However, keep the same case as the original text.

If there are more characters in R than F, the extra characters should be the same case as they are in R. If there are numbers or symbols in F, then the corresponding characters in R should keep the case they have in R. F will not necessarily appear in T.

You can assume all text will be in the printable ASCII range.

Examples

"Text input", "text", "test" -&gt; "Test input"

"tHiS Is a PiEcE oF tExT", "is", "abcde" -&gt; "tHaBcde Abcde a PiEcE oF tExT"

"The birch canoe slid on the smooth planks", "o", " OH MY " -&gt; "The birch can OH MY e slid  OH MY n the sm OH MY  OH MY th planks"

"The score was 10 to 5", "10", "tEn" -&gt; "The score was tEn to 5"

"I wrote my code in Brain$#@!", "$#@!", "Friend" -&gt; "I wrote my code in BrainFriend"

"This challenge was created by Andrew Piliser", "Andrew Piliser", "Martin Ender" -&gt; "This challenge was created by Martin Ender"

// Has a match, but does not match case 
"John does not know", "John Doe", "Jane Doe" -&gt; "Jane does not know"

// No match
"Glue the sheet to the dark blue background", "Glue the sheet to the dark-blue background", "foo" -&gt; "Glue the sheet to the dark blue background"

// Only take full matches
"aaa", "aa", "b" -&gt; "ba"

// Apply matching once across the string as a whole, do not iterate on replaced text
"aaaa", "aa", "a" -&gt; "aa"

"TeXT input", "text", "test" -&gt; "TeST input"


Sandbox link
APL (Dyalog), 75 73 72 bytes



Prompts for T, R, and F in that order. R must b given in Dyalog transformation format and F must be given in PCRE format.

⍞⎕R(⍞∘{(⊣⌿d)l¨⍨(1∘⌷≠(⊢⌿d∊⎕A,l⎕A)∧≠⌿)d≠(l←819⌶)d←↑⍺⍵.Match↑¨⍨≢⍺})⍠1⊢⍞


Try it online!

⍞ prompt for T

⊢ yield that (separates 1 and T)

⍞⎕R(…)⍠1 prompt for F and Replace matches with the result of the following function:

 ⍞∘{…} derive a monadic function by tying the prompted-for R as left argument to:

  ≢⍺ count the number of letters in R

  ⍺⍵.Match↑¨⍨ take that many letters from each of R and the match
   ⍺ is the left argument, which we tied R as.
   ⍵ is a namespace in which Match contains the currently found string.

  ↑ mix those two into a two-row matrix

  d← store as d

  (…)  apply the following tacit function to that:

   819⌶ lowercase (mnemonic: 819 looks like Big)

   l← store that function as as l

  d≠ Boolean where d differs (i.e. gives 0/1 for each lowercase/uppercase letter)

  (…) apply the following tacit function to that:

   ≠⌿ vertical XOR

   (…)∧ Boolean AND with the following array:

    l⎕A lowercased Alphabet

    ⎕A, prepend uppercase Alphabet

    d∊ Boolean for each letter in d whether a member of that (i.e. whether a letter)

    ⊢⌿ last row i.e. for character of the match whether it is a letter

   1∘⌷≠ XOR with the first row, i.e. whether each character of R is uppercase

  (…)l¨⍨ use that to lowercase (if 0) or uppercase (if 1) each letter of:

   ⊣⌿ the first row, i.e. R



* Byte count for Dyalog Classic using ⎕OPT  instead of ⍠.