[Question]
  [
Given a string and a substring and a positive integer `n`.
Remove the `n` occurences of a substring from the *end* of the **originally given string**. If the substring is not present in the string or the number of times the substring appears is less than `n`, then the output is the original string. No space should be present in place of the removed substring.
### RULES
1. The shortest code wins the challenge (as this is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'")).
### Test-cases:
```
Input:
String = "Cats do meow-meow while lions do not meow."
Substring = "meow"
n = 2
Output:
"Cats do meow- while lions do not ."
Input:
String = "Cats do not memeowow, they do meow-ing."
Substring = "meow"
n = 2
Output:
"Cats do not meow, they do -ing."
Input:
String = "Cats do meow-meow while lions do not meow."
Substring = "meow"
n = 4
Output:
"Cats do meow-meow while lions do not meow."
```
  
[Answer]
# Excel (ms365), ~~115~~, 83 bytes
-32 also thanks to [@jdt](https://codegolf.stackexchange.com/users/41374/jdt) and the idea to split instead of loop.
```
=LET(a,TEXTSPLIT(A1,,B1),b,ROWS(a),IF(b>C1,CONCAT(IF(SEQUENCE(b)<b-C1,a&B1,a)),A1))
```
[![enter image description here](https://i.stack.imgur.com/igedA.png)](https://i.stack.imgur.com/igedA.png)
---
**Note**: This answer has been edited to no longer loop to remove the substring from the *end* of the string, but split the input instead. This would now give the appropriate answer for input like 'Cats do meow not memeowow, they do meow-ing.' where 'n=3'.
[Answer]
# [Python](https://www.python.org), ~~66~~ ~~53~~ 52 bytes
* -1 byte thanks to @92.100.97.109 (though not exactly in the way they intended)
```
lambda i,j,k:[i,''.join(a:=i.rsplit(j,k))][len(a)>k]
```
[Attempt This Online!](https://ato.pxeger.com/run?1=m72soLIkIz9vweI025ilpSVpuhY3TXISc5NSEhUydbJ0sq2iM3XU1fWy8jPzNBKtbDP1iooLcjJLNIBSmpqx0TmpQGFNu-xYqN5pBUWZeSUaaRpKSflFCiUIrKSjoAShjDQ1FZQVfPOLUhVKMhLzFPy4sOlBV-9akZhcklOpkFpYmpgDVIBFG7oWn9TiYqgVENctWAChAQ)
Returning identity when the occurrences are less than N is annoying.
[Answer]
# [C (clang)](http://clang.llvm.org/), ~~109~~ ~~107~~ ~~112~~ ~~105~~ 100 bytes
-11 bytes thanks to [c--](https://codegolf.stackexchange.com/users/112488/c)
-2 bytes thanks to [ceilingcat](https://codegolf.stackexchange.com/users/52904/ceilingcat)
+5 bytes for fixing an error pointed out by [JvdV](https://codegolf.stackexchange.com/users/100057/jvdv).
```
f(*a,i,*b,j,n,**r){for(*r=wcsdup(a);i--*n>0;)!bcmp(a+i,b,j)?wcscpy(a+i,a+i+j),n--,i-=j:0;!n?*r=a:0;}
```
[Try it online!](https://tio.run/##lZJRT4MwEMff9yk6kimF6yTzxYhzD776DeYeWAezC2sJLWFz4auLV5gOJDGzSXPXP//@uNyVM55GclvXietFIMBbww4keF5OT4nKXS@fl1xvisyNaCgY8@RzENLxmu9R8QWgnS7QwbNjc8bt7yhIxkCw@e4xCMdygZAIs6oW0pB9JKRLR6cRwaVNXnDTpK1gl3WZg1k@BKuwJ@ZxNhS5KqRppYqYWJvlisw7tBN5dfaxKqcOnDNMZqSCnuMlMppsFJEKK4ytS5VAzHt8tKo9MyG3VyHs939w7n9z1ion5rIbbxtnf1ivsPUtbcfaxuGkiWubKbB1QYjhiWjxEavEtR2l5K57XAYrih7fp8PBeXZyCDk/msYuVlMUadj34TCHPhSHPl2k5iJiDQcD9mIaS5tTsKwfxSKAfAOb1wHkpqV02FmO9MR1biepvgVyDpMN1tTkb9K5UJo/dmoc8Hv4alTVnzxJo62uWfkF "C (clang) – Try It Online")
[Answer]
# T-SQL 135 bytes
Is not looping to avoid the string being created again "memeowow"
```
WITH c(z)as(SELECT 1UNION ALL 
SELECT charindex(@r,@,z+1)FROM c WHERE z>0)SELECT top(@n)@=stuff(@,z,len(@r),'')FROM
c ORDER BY-z PRINT @
```
**[Try it online](https://data.stackexchange.com/stackoverflow/query/1660456/remove-a-given-substring-n-number-of-times-from-the-end-of-a-string)**
[Answer]
### Python, 51 bytes
```
lambda A,B,n:"".join(A.rsplit(B,n*(n<=A.count(B))))
```
[Answer]
# [Ruby](https://www.ruby-lang.org/), ~~67~~ ~~61~~ 75 bytes
Updated after clarification by OP, which unfortunately made it longer.
```
->s,u,n,*a{s.scan(u){a<<$`.size}
a.size<n||eval("s[a.pop,u.size]='';"*n)
s}
```
[Attempt This Online!](https://ato.pxeger.com/run?1=m72kqDSpcsEiN9ulpSVpuhY3vXXtinVKdfJ0tBKri_WKkxPzNEo1qxNtbFQS9Iozq1JruRLBtE1eTU1qWWKOhlJxdKJeQX6BTilYPNZWXd1aSStPk6u4Fmrk3YLSkmIFt2gl50QgnZKvkJuaX64LIhTKMzJzUhVyMvPzwBJ5-SVgST0lHQUlEANIG8VyoeuHKAPJ55frKJRkpFbCTc3MS8enmQjDwe7CbwOSAcaxEE8uWAChAQ)
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E/wiki/Commands), 13 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)
```
¡`.gI›I*F«}¹ý
```
Inputs in the order `substring, string, n`.
[Try it online](https://tio.run/##yy9OTMpM/f//0MIEvXTPRw27PLXcDq2uPbTz8N7//3NT88u5nBNLihVS8hVAHF0QoVCekZmTqpCTmZ8HlsjLLwFL6nEZAQA) or [verify some more `n`](https://tio.run/##yy9OTMpM/W96bJKfvZLCo7ZJCkr2hzYd2vn/0MIEvXS/Rw27/LTcDq2uPbTz8N7/Ov9zU/PLuZwTS4oVUvIVQBxdEKFQnpGZk6qQk5mfB5bIyy8BS@oBAA).
**Explanation:**
```
¡           # Split the (implicit) second input-sentence on the (implicit) first substring
 `          # Pop and push all parts separated to the stack
  .g        # Get the amount of items on the stack
    I›      # Check if this is larger than the third input-integer `n`
      I*    # Multiply it by the third input-integer `n`
        F   # Loop that many times:
         «  #  Concat the top two parts on the stack together
        }¹ý # After the loop: join the stack with the first input substring as delimiter
            # (after which the result is output implicitly)
```
[Answer]
# [Pip](https://github.com/dloscutoff/pip), 30 bytes
```
d:a^b#d>c?dZJ(bRL#d-UcALxRLc)a
```
[Try It Online!](https://dso.surge.sh/#@WyJwaXAiLCIiLCJkOmFeYiNkPmM/ZFpKKGJSTCNkLVVjQUx4UkxjKWEiLCIiLCIiLCJcIkNhdHMgZG8gbWVvdy1tZW93IHdoaWxlIGxpb25zIGRvIG5vdCBtZW93LlwiIFwibWVvd1wiIDIiXQ==)
How?
```
d:a^b#d>c?dZJ(bRL#d-UcALxRLc)a
  a                            : First arg(string)
    b                          : Second arg(substring)
        c                      : Third arg(n)
d:                             : Assign d to the result of
  a^b                          : Split a on separator b
         ?                     : If
     #d>c                      : Length of d is greater then c
                    Uc           : Increment c
             bRL                 : Repeat b 
                #d-              : Length of d - c times
                      AL         : Append list
                        x        : Empty String
                         RL      : Repeat x
                           c     : c times
          dZJ                    : Zip with iterable d
                             a : Else return a
```
[Answer]
# JavaScript (ES6), 62 bytes
Expects `(string, substring, n)`.
```
(s,q,n)=>(a=s.split(q))[n]+1?a.map(s=>a[++n]+1?s+q:s).join``:s
```
[Try it online!](https://tio.run/##HYrNCoMwEITvfYrFU0I0IPSkjT30MaRg8KeNxF11Qz2UPnuqXuYb5pvRfiy3q5tDhtT1cTBRcLqkKE0lrGHNs3dBLFLW@FT53erJzoJNZWulzoXVUrDUIzlsmoLjQKtAMJCXgHAzcN2plITvBaAlZPK99vQSg0geNjB0BFNPW3YEbG/ne/Bu/x0CKZxSJykkR9mJUpaXX/wD "JavaScript (Node.js) – Try It Online")
### Commented
```
(s, q, n) => (   // s = string, q = substring, n = integer
  a = s.split(q) // split s on q and save the result in a[]
                 // if q appears x times, we get x + 1 entries
                 // some of these entries may be empty strings (falsy)
                 // so we do '+ 1' to distinguish between empty and undefined
)[n] + 1 ?       // if a[n] is defined:
  a.map(s =>     //   for each entry s in a[]:
    a[++n] + 1 ? //     increment n; if a[n] is still defined:
      s + q      //       append q to s
    :            //     else:
      s          //       leave s unchanged
  ).join``       //   end of map(); join everything back together
:                // else:
  s              //   return s unchanged
```
[Answer]
# [Vyxal](https://github.com/Vyxal/Vyxal) `s`, 11 bytes
```
O≤[Ẇy?NẎY|_
```
[Try it Online!](https://vyxal.pythonanywhere.com/#WyJzIiwiIiwiT+KJpFvhuoZ5P07huo5ZfF8iLCIiLCJtZW93XG5DYXRzIGRvIG5vdCBtZW1lb3dvdywgdGhleSBkbyBtZW93LWluZy5cbjIiXQ==)
12 bytes without the flag. Takes `substring, text, n`
## Explained
```
O≤[Ẇy?NẎY|_
O≤          # is the count of the substring in text less than n?
  [      |  # if so:
   Ẇy       #   Split text on substring, keeping the delimiter. Then uninterleave - this gives a list of splits and a list of delimiters
     ?NẎ    #   Take up to the -nth item of the list of delimiters
        Y   #   Reinterleave the delimiters, which will now be shorter than before. The s flag combines all the pieces into a single sting
         |_ # Otherwise, just return the original text
```
[Answer]
# [Desmos](https://desmos.com/calculator), 169 bytes
```
S=s.length
L=l.length
I=[L-S...1]
A=I[[(l[i...i+S]-s)^2.totalfori=I]=0]
B=\{n>A.\length:[-L],A[1...n]\}
f(l,s,n)=l[[[0^{(b-B)^2}.maxforb=z-[0...S-1]].maxforz=[1...L]]=0]
```
[Try It On Desmos!](https://www.desmos.com/calculator/6ebtzvfzgh)
[Try It On Desmos! - Prettified](https://www.desmos.com/calculator/h4iuopiqfa)
\$f(l,s,n)\$ takes in two lists of codepoints, with \$l\$ representing the string and \$s\$ representing the substring, and a positive integer \$n\$, representing the number of substrings to remove. The output is also a list of codepoints.
As you can tell by the byte size of the code, Desmos is not really well suited for problems related with string manipulation (When was using Desmos on a string problem ever a good idea?!?!). Also fun fact, this is my first time using a nested list comprehension in Desmos, which is pretty nice. There's probably a better way of doing that part, but nested list comprehensions look cool :P (to be completely honest, I can't think of any better way to do that lol).
[Answer]
# [Red](http://www.red-lang.org), 89 bytes
```
func[s t n][reverse t either parse r: reverse copy s[n to remove t to end][reverse r][s]]
```
[Try it online!](https://tio.run/##lU4xDsIwDNz7ilNnYEBMXfkBa5ShahwaqY0rJ1D19SFpVRASCx5sn@/OtpBJNzJKV7ZBsg/fqYAIr5XQkyRQBuRiT4KpLVAa7EzH04KgPCLn2cjPIs49efOxi1ZB62RZqO167Nsr5KivbQwwjJF4PpaEuXcDYXDsV8JzXMlTjbrUGudv5yYoFM8H5D@X9z7n79lWxD@df9y8VFpN4nyExfZ/egE "Red – Try It Online")
Working on a reversed copy of the string, I use `parse` to remove `n` times the reversed substring. If `parse` succeeds, I return the modified string reversed, otherwise - the original string.
[Answer]
# [Japt](https://github.com/ETHproductions/japt) v2.0a0, 21 [bytes](https://en.wikipedia.org/wiki/ISO/IEC_8859-1)
```
qW ÔË+WpE>VÃw
qWpUÊ§V
```
[Try it](https://petershaggynoble.github.io/Japt-Interpreter/?v=2.0a0&code=cVcg1MsrV3BFPlbDdwpxV3BVyqdW&input=IkNhdHMgZG8gbWVvdyBub3QgbWVtZW93b3csIHRoZXkgZG8gbWVvdy1pbmciLCA0LCAibWVvdyI)
Input as `string, n, substring`
v2.0a0 is necessary because v1.4.6 errors if you try to use `p` this way.
Explanation:
```
qW ÔË+WpE>VÃw
qW            # Split <string> where <substring> appears
   Ô          # Reverse the array
    Ë      Ã  # For each item in the array:
     +        #  Append:
      Wp      #   <substring> repeated a number of times equal to:
        E>V   #    The current index is greater than <n>
              #    (Boolean gets converted to 1 or 0)
            w # Reverse the new array
              # Store as U
qWpUÊ§V
q             # Turn U into a string by inserting this between each item:
 Wp           #  <substring> repeated a number of times equal to:
   UÊ         #   Length of U (i.e. 1 + number of times <substring> appeared)
     §V       #   Is less than or equal to <n>
              # Output that string
```
I've tried an alternate using `ð` but the best I got was [25 bytes](https://petershaggynoble.github.io/Japt-Interpreter/?v=2.0a0&code=VvBVIArKqFc/X2pVbyBOzmx9Z1dbVl06Vg&input=Im1lb3ciLCAiQ2F0cyBkbyBtZW93IG5vdCBtZW1lb3dvdywgdGhleSBkbyBtZW93LWluZyIsIDM).
[Answer]
# [Pyth](https://github.com/isaacg1/pyth), 21 bytes
```
s.iJcwz*]zt-lJ*KE>lJK
```
[Try it online!](https://tio.run/##K6gsyfj/v1gv0yu5vEortqpEN8dLy9vVLsfL@///3NT8ci7nxJJihZR8hbz8EoXcVJBQfrmOQklGaiVIFMTXzcxL1@MyAgA "Pyth – Try It Online")
### Explanation
```
s                        concatenate the elements of
 .i                      interleave
   Jcwz                  the input string split on the substring (assigned to J) and
        ]z               a singleton list of the substring
       *                 duplicated
          t              one less than
           -lJ           the length of J minus
              *KE>lJK    0 if substring has less than n occurrences, n otherwise
```
[Answer]
# [simply](https://github.com/ismael-miguel/simply), 99 bytes
Creates an anonymous function that returns the expected result.
The argument order is `$full_string`, `$substring` and then `$number`.
```
fn($F$S$N)&iff(run&len(&str_split($F$S))>$N&str_rev(&str_replace(&str_rev($F)&str_rev($S)''$N))$F);
```
## How does it work?
First, splits the full string by the substring, and counts the number of elements.
When splitting the string:
* If the substring isn't present, returns 1 element.
* If it is present, returns 1 extra element.  
Example: `&str_split("abcbdbebf", 'b') -> ["a", "c", "d", "e", "f"]`  
For 4 `'b'`s, returns 5 elements.
If the number of elements is higher than `$number`, that means there's at least `$number` substrings in the full string.
The `&iff()` function is just the same as a ternary operator, in C-like languages.
To remove from the end of the string, I need to reverse the string, since there isn't a way to indicate to remove from the end of the string.  
However, it takes an argument that indicates how many times to replace, which means, it will replace up to `$number` occurrences.
The result is returned automatically, since it is a function without a scope, just like an arrow function in JavaScript.
## Ungolfed
Code-y looking:
```
$fn = fn($full_string, $substring, $num) => &iff(
    (call &len(&str_split($full_string, $substring))) > $num,
    &str_rev(
        &str_replace(
            &str_rev($full_string),
            &str_rev($substring),
            '', $num
        )
    ),
    $full_string
);
```
Pseudo-code looking:
```
Set $fn to an anonymous function ($full_string, $substring, $num)
Begin.
    Set $count to the result of calling &len(Call &str_split($full_string, $substring)).
    
    Return the result of calling &iff(
        $count > $num,
        Call &str_rev(
            Call &str_replace(
                Call &str_rev($full_string),
                Call &str_rev($substring),
                '', $num
            )
        ),
        $full_string
    ).
End.
```
[Answer]
# [Retina 0.8.2](https://github.com/m-ender/retina/wiki/The-Language/a950ad7d925ec9316e3e2fb2cf5d49fd15d23e3d), 87 bytes
```
.+$
$*
(?=.*¶(.+)¶)\1
¶
rT`¶``(?(1)$)(?<-1>¶.*)+(?=¶.+¶(1)+$)
+`¶(.*¶(.+)¶1+$)
$2$1
1G`
```
[Try it online!](https://tio.run/##PYsxCgMhEEX7OYWFheOwwmydxGKLXCBlChciRNgobIS9mQfwYka3SPP4/P/@7nOIa2uGJEgNyl6NrkUZwlrwyVAL7A9Xi3PKKkaJyl4mvtViNFK3e6DuM5JEIDeu/z@PTs6Sge@utWXNX/FK4uPTMQ2I4x02L7aQ4jnElM/RwCDMPw "Retina 0.8.2 – Try It Online") Takes the string, substring and count on three separate lines. Explanation:
```
.+$
$*
```
Convert the count to unary.
```
(?=.*¶(.+)¶)\1
¶
```
Replace occurrences of the substring in the string with newlines.
```
rT`¶``(?(1)$)(?<-1>¶.*)+(?=¶.+¶(1)+$)
```
Remove the last `n` newlines from the string if there are in fact that many. (Today I discovered that an empty "to" string in transliteration is treated as `_`, i.e. delete matching characters.) The `r` causes the regular expression to be evaluated from right to left, so the lookahead gets processed first (setting `$#1`), then the newline-matching loop in the middle, then the count check at the beginning.
```
+`¶(.*¶(.+)¶1+$)
$2$1
```
Replace (remaining) newlines with the substring.
```
1G`
```
Keep only the (final) string.
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), 25 bytes
```
Ｎθ≔⪪ηζηＦ›Ｌηθ⊞η⪫⮌Ｅ⊕θ⊟ηω⪫ηζ
```
[Try it online!](https://tio.run/##HY1NDoIwEIX3nGKW0wRduGVlXBiMGqInqDDSJmVa2gKJl6@lm5fJfO@nV9L3VpqUWnZLfC7ThzzOoqnOIeiR8e2Mjqhq@IkaVP5/rQe8epIxG@/EY1SoMpuFgG4JavferGZ80Uo@ED6kw5Z7TxNxpCGX19BZl0MiX5vInZ3XHLGkypJoUjpVFxkDDBYmstthF9iUNgRGWy6AbSzwWO2aDqv5Aw "Charcoal – Try It Online") Link is to verbose version of code. Takes inputs in the order count, string, substring. Explanation:
```
Ｎθ
```
Input the count as an integer.
```
≔⪪ηζη
```
Split the string on the substring.
```
Ｆ›Ｌηθ
```
If this results in more than enough pieces, then...
```
⊞η⪫⮌Ｅ⊕θ⊟ηω
```
... join the last `n+1` pieces together.
```
⪫ηζ
```
Join the (remaining) pieces with the substring.
[Answer]
# PHP 8.x, 65 bytes
This anonymous function does the replacement, up to `$n`, and checks how many replacements were made.  
If there were fewer than `$n` replacements made, returns the original string.
```
fn($F,$S,$N)=>($r=preg_replace("@$S@",'',$F,$N,$x))&&$N>$x?$F:$r;
```
Due to the use of [`preg_replace`](https://www.php.net/manual/en/function.preg-replace.php), the substring must be a valid regular expression.  
Regular words will always be valid regular expressions, and there's no need to worry about it.
## How does it work?
The function [`preg_replace`](https://www.php.net/manual/en/function.preg-replace.php) takes the following arguments:
* `$pattern` - Which will be the substring, `$S`
* `$replacement` - Which is an empty string
* `$subject` - The full string, `$F`
* `$limit` - Maximum number of replacements, `$N`
* `&$count` - Variable which will hold the number of replacements made
If `$N` is higher than `$count`, returns the full string, otherwise returns the result of the replacement.
# Example
```
$fn=fn($F,$S,$N)=>($r=preg_replace("@$S@",'',$F,$N,$x))&&$N>$x?$F:$r;
echo $fn('Cats do not memeowow, they do meow-ing.', 'meow', 2);
// Should display: Cats do not meow, they do -ing.
```
You can try this on <https://onlinephp.io/c/d08f3>
[Answer]
# [PHP](https://php.net/), 75 111 bytes
Okay so... lot of change
+12 bytes for a bug found by @Ismael Miguel where loop keep running if no instance of searched string given (`strrpos()===false`)
+26 bytes for using $argv instead or pre defined variable as indicated by @Sʨɠɠan
-2 bytes (Hey! an actual upgrade :D) from @Sʨɠɠan who remind me i can just get ride of `{}` for a single line instruction ^^'
```
for($s=$argv[1];$argv[3]--&&false!==$c=strrpos($s,$argv[2]);)$s=substr($s,0,$c).substr($s,$c+strlen($argv[2]));
```
[Try it online!](https://tio.run/##RYtBDsIgEEWvgglpSmwbtUskLjyGYYFIpQkyhEF7fIQ20c3Ln3n/Bxvy@RIKJ4gtRUFVfH5uR8m3MMq@b5pJOTQ7IagWmGIMgKXabY2TZJyVIb7vxdX/oaOaDf@b6n1Jzvj2t2A8G22BUOQ5X1VC8gDyMrD0FWSxszPEzeBX4SGtcsiVefwC "PHP – Try It Online")
[Answer]
# [Raku](https://raku.org), 42 bytes
```
{$^a.flip.subst($^b.flip,'',:x($^c)).flip}
```
[Try it online!](https://tio.run/##K0gtyjH7n1upoJamYPu/WiUuUS8tJ7NAr7g0qbhEQyUuCczVUVfXsaoAcpM1NcECtf@tixMrFdIUlJwTS4oVUvIVclPzy3VBhEJ5RmZOqkJOZn4eWCIvvwQsqaekowSilXSMuNA1Q9SAZPPLdRRKMlIr4UZm5qXj00mCtSZc/wE)
[Answer]
# Shell, ~~238~~ ~~236~~ ~~220~~ ~~200~~ ~~199~~ ~~194~~ ~~191~~ 186 bytes
(counting the last newline to make the script file containing those commands a real unix text file. Otherwise 185 bytes.)
Can probably be highly optimized, but I found it funny to attempt.
usage: cat Text-cases | this\_script , or this\_script < Test-cases
```
sed -e'/^O/N;s,\n,,;s,",,g;s, = ,:,g'|awk -F: '/^St/{I=$2}
/^Su/{S=$2}
/^n/{n=$2
R=s=""
for(i=1;i<=n;i++){R=R sprintf("\\(.*\\)%s",S)
s=s"\\"i}
system("echo "I"|sed -e\"s,"R","s",\"")}'
```
Explanation:
```
the sed : 
  1) put the line following "Output:" at the end of that line
  2) takes out the doublequotes
  3) replace " = " by ":"
Then the awk:
  retrieve (I)nput String,
           (S)ubstring, 
       and (n),
  loops on n to construct:
         the (r)egex "\(.*\)S\(.*\)S\(.*\)S" (if n==3)
     and its (s)ubstitution "\1\2\3"
  and use sed to do this search/replace on the (I)nput string.
I used "\n" instead of ";" when I could (in the awk part) as it 
is 1 caracter all the same, and is more legible.
```
[Answer]
# [Perl 5](https://www.perl.org/), 74 bytes
```
sub{($_,$s,$n)=@_;$n*2>(@a=split/($s)/)?$_:join'',grep!/$s/||++$n*2<@a,@a}
```
[Try it online!](https://tio.run/##rZJdT8IwFIav3a84LsVtUlgc6AVzsMRLErnxTs0ypRvT0c61Bgnw22e7AUocfjdpz2l73vdp02YkT08LFHkFf75bmCjAiGNELc8PXESPnb7phx7P0kTYJuKWbQ1Q0HtgCTUMHOckO7QRt5fLZlMVn/sh9sNV4WoRy03tWr8IBYcxgylhs5YaYDZJUgJpwmi5QZkoN9s6Bl0lMjrg9WFXWidr67f4HaJyUtVshkFMyHyrTmis/GWrR2wO8SarJDv@P7pC9@MVPpf@HnXyfdRfMJ0dzL8/SKfmQfZLJcdaaEo/nctfKXK5igHJH7zNqezkJSP3wgIPfBS463pAsXT34AhF@6RWVZvJuYhAb7TOOECj1XU4LFUsw7jKN2sOv6E61g7WUCBPFWgABns0oAfG5egKRkMDl96qfXVwXDq42qp4BQ "Perl 5 – Try It Online")
[Answer]
# [Ruby](https://www.ruby-lang.org/), 64 bytes
`->s,u,n,*a{x=s.split(u);l=x.size-n;x[0...l].join(u)+x[l..].join}`
[Try it online!](https://ato.pxeger.com/run?1=m72kqDSpcsEiN9ulpSVpuhY3HXTtinVKdfJ0tBKrK2yL9YoLcjJLNEo1rXNsK_SKM6tSdfOsK6IN9PT0cmL1svIz84By2hXROXp6EG4t1Jy7BaUlxQpu0UrOiUA6JV8hNzW_XBdEKJRnZOakKuRk5ueBJfLyS8CSeko6CkogBpA2iuVC1w9RBpLPL9dRKMlIrYSbmpmXjk8zEYaD3YXfBiQDjGMhnlywAEIDAA)
Code is mine - I thought `split` and `join` would be more efficient, but I will credit [Jordan](https://codegolf.stackexchange.com/users/11261/jordan) above for the tests and framework.
[Answer]
# [K (ngn/k)](https://codeberg.org/ngn/k), 46 bytes
```
{x(!#x)^,/(!#y)+/:(-z*(~z>#t))#t:&(#y)(y~)':x}
```
[Try it online!](https://ngn.codeberg.page/k#eJytUU1PwkAQve+vWKhhZ0ppKXpxEr146smDPTZ0MRZogruGbm0Lpb/dLURNlBgOXmYyH++9eZkl7WsYODXOvcDmBscBwWTnQre7dwyiY2gEtg1Nh4LqA2MBY5F6Kw09LEzBXzR/zXQ16QOv1vkm45tcq+NAaXMc+uypfC7MNlcr6mumaMYeS/OL5ByB/1PuxNrv68rjZp01X3grcInW513f6BPyH3zdnPX1N0lihQlcg951agja5HZ255LAdEpysV2985DFJHNZSCX1wL4H3HZIwwRFmKJIgzaEUedYQBIxBktf7KHu19GT0VUt1UHE2AkYxyg1+wDGfJ8U)
[Answer]
# [Python 3](https://docs.python.org/3/), 78 bytes
```
i=input
a=i()
b=i()
c=int(i())
d=a.rsplit(b,c)
print([a,''.join(d)][len(d)>c])
```
Pretty direct approach using Python 3. [Try it online!](https://tio.run/##K6gsycjPM/7/P9M2M6@gtIQr0TZTQ5MrCUwmA8VKNIAsTa4U20S9ouKCnMwSjSSdZE2ugiKQVHSijrq6XlZ@Zp5GimZsdE4qiLZLjtX8/z8pv0ihBIG5QNgIAA "Python 3 – Try It Online")
]