[Question]
  [
## Objective
Create a function to reverse string concatenation 
## Input
Two strings (alphanumeric + spaces), where one should be subtracted for the other.
* You can assume that the string to be subtracted will never be larger than the other one.
## Output
The result from the subtraction
## Subtraction
You should remove one string from the start or the end of another string.
If the string is present in the start and in the end, you can only remove one, which one will be removed is up to you.  
If the string isn't in the start or in the end, or isn't an exact match, it is an invalid subtraction and you should output the original string.
## Test Cases
### Valid Subtraction
```
'abcde','ab' -> 'cde'
'abcde','cde' -> 'ab'
'abab','ab' -> 'ab'
'abcab','ab' -> 'abc' or 'cab'
'ababcde','ab' -> 'abcde'
'acdbcd','cd' -> 'acdb'
'abcde','abcde' -> ''
'abcde','' -> 'abcde'
'','' -> ''
```
### Invalid Subtraction (returns original string)
```
'abcde','ae' -> 'abcde'
'abcde','aa' -> 'abcde'
'abcde','bcd' -> 'abcde'
'abcde','xab' -> 'abcde'
'abcde','yde' -> 'abcde'
```
### Invalid Input (don't need to be handled)
```
'','a' -> ''
```
This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), so the shortest code in bytes wins!
  
[Answer]
# Java 8, ~~46~~ ~~45~~ ~~44~~ 40 bytes
-1 byte thanks to TheLethalCoder
-1 byte because I'm dumb (thanks Rod!)
-4 bytes thanks to Kevin Cruijssen
```
a->b->a.replaceFirst("^"+b+"|"+b+"$","")
```
[Try it online!](https://tio.run/nexus/java-openjdk#dVNNb8IwDL33V1jRDu1aKti1Awkm7bbTjoxJThtYpn4pSdEQ47cz94M2jJJDEtvvvcSxc5ZZWSgD37jHsDIyDR8jJ05Ra3hDmcPRARplxVMZgzZoaNkXMoGMou67UTLfrTeAaqe9DlyPFaSY8QRhDjhZ8MkCQyXKFGPxKpU2LvtkPvfZbzM/sIAxL3J6di9rhDYvqIUmnSMw5HEiWFBvWNCjB3ez2P4ad4u@JxMnFGh1RuW7zUjEdv63B/o4F3HUze9c4udO7ofrqzXKrLdP1utuC@XK3ICkR51GIP0ZPA8vHaYi35kv8oM/hye7qE1pDtqILCwqE5ZUJJPmLvtgDHyrVmu5IZvcAdyG/FkXhMmiC6sqd9t2CQYoiVxZxPNaYt0qfV7OMF83adtDjfYKeHCxqVGntjGzE1TCVCoHHnK3xnkhug0ksk6hnIXaUiNTjw/MJfDuMwC/A19a8Mv5Fw72nNP5/Ac "Java (OpenJDK 8) – TIO Nexus") (includes all test cases)
A Java answer actually beats a few other practical languages. *Smiles. (and now it beats JS!)*
[Answer]
# [Brachylog](https://github.com/JCumin/Brachylog) (Try It Online!), 12 bytes
```
~cpĊh.∧Ċtw|w
```
[Try it online!](https://tio.run/nexus/brachylog2#@1@XXHCkK0PvUcfyI10l5TXl//8rJSYlp6Qq/VdKTlECAA "Brachylog – TIO Nexus")
Takes the string to subtract from from standard input, and the string to subtract as a command line argument.
## Explanation
```
~cpĊh.∧Ċtw|w
~c            Split {the input} into pieces
  p           and (possibly) rearrange those pieces
   Ċ          such that there are two pieces
    h         and the first
     .        matches the command line argument
      ∧       then
         w    print
        t     the last
       Ċ      piece.
          |   If all else fails,
           w  print {the input}.
```
[Answer]
# JavaScript (ES6), 41 bytes
```
s=>t=>s.replace(eval(`/^${t}|${t}$/`),'')
```
Takes input via currying syntax, i.e. `f("abab")("ab")`.
[Answer]
# [Retina](https://github.com/m-ender/retina), 21 bytes
1 byte thanks to Martin Ender.
```
(.*);(\1|(.*)\1$|)
$3
```
[Try it online!](https://tio.run/nexus/retina#U9VwT/ivoaelaa0RY1gDYsQYqtRocqkY//@fmGSdmJScksoFxFAWWCgxCUInwxgwOYQ6GMWVCNeZCGUACSirAm5BJUwjAA "Retina – TIO Nexus")
[Answer]
# JavaScript (ES6), ~~76~~ ~~70~~ ~~45~~ 41 bytes
```
s=>t=>s.replace(RegExp(`^${t}|${t}$`),"")
```
---
## Try It
```
f=
s=>t=>s.replace(RegExp(`^${t}|${t}$`),"")
o.innerText=f(i.value="abcde")(j.value="ab")
i.oninput=j.oninput=_=>o.innerText=f(i.value)(j.value)
```
```
<input id=i><input id=j><pre id=o>
```
[Answer]
# [Perl 6](https://perl6.org), 21 bytes
```
->$_,$b {S/^$b|$b$//}
```
[Try it](https://tio.run/nexus/perl6#bY5dToNAFIXfZxU3DXVAB9AXY0pL3IO@WTUw3BoS/sLQpk3FxeijSzB96Ya6BDoDFKH6MnfmO@eeM0uBsLq1uEPiDVzwNECYVaarvTLNh@2D/aL575qv2XZZKcd9gaKAGURhgkI3rNjLJlsC8LH/jidvYMNh90kPuy@Y6jA1n@izewmG21GblGQpGx9likOyyEvgqo50yCLN23TTBX0eJmHB5jnG6QrZHNcZ8gIDA1RZKEB9VK89jcVgcPIwEFkeJsUCRuOba8FgfCdAhco5YtDfYl3u/sfKMI9IWVHP5wFSJidVW1S9SEfVWWMpKyrHr7VlfAB55xzmNm@p8EDe6uhWkKDX2Mxa6dFhRgf6e3jWc@Le/9zv@s@E9Z8ft8ImGFQcAQ "Perl 6 – TIO Nexus")
## Expanded:
```
-> $_, $b {   # pointy block lambda
  S/          # Str replace and return (implicitly against ｢$_｣)
  |   ^ $b    # starting with the second argument
  |     $b $  # or ending with the second argument
  //          # replace with nothing.
}
```
[Answer]
# [Japt](https://github.com/ETHproductions/japt), ~~11~~ 9 bytes
```
k"^|$"¬qV
```
[Try it online!](https://tio.run/nexus/japt#@5@tFFejonRoTWHY//9KiUnJKalpSjoKSiAKAA "Japt – TIO Nexus")
[Answer]
# TI-Basic (TI-84 Plus CE), 63 bytes
```
Prompt Str0,Str2
inString(Str0,Str2
If Ans
sub(Str0,1,Ans-1)+sub(Str0,Ans+length(Str2),length(Str0)-Ans+1-length(Str2→Str0
Str0
```
[Answer]
## Mathematica, 162 bytes
```
(c=Characters;a=c@#;b=c@#2;l=Length;t={};If[l@Intersection[a,b]==l@b,If[MemberQ[Partition[a,l@b,1],b],t=a;Table[t=DeleteCases[t,b[[i]],1,1],{i,l@b}]],t=a];""<>t)&
```
test input style ["abcde","ab"]
[Answer]
# Python, ~~69~~ ~~68~~ ~~64~~ ~~57~~ ~~51~~ 45 bytes
This ended up being a completely different solution with Regex.
*Thanks to [Value Ink](https://codegolf.stackexchange.com/users/52194) for -2 bytes!*  
*and [Felipe Nardi Batista](https://codegolf.stackexchange.com/users/66418/) for the massive -6 bytes!*
```
import re
lambda s,c:re.sub(c+'$|^'+c,'',s,1)
```
[Try it online!](https://tio.run/nexus/python3#hZHLCsIwEEX3fsUIwiQaBLdCF/6HCHkVArWGTgQF/71OH1KtrW4yyb1nJpckz451oc/GaSBl95Xf0tUIu8HV44QbqxAVqZ1chHO8VAkqX2siz7tcoDbWeVRcUUKWATbHxbffrB3A5IfP57f2sWsHO5TQKqj4lkYZjRkF6YR3xjqW2iwvhJWpsF3tmCl/7obBmpzqZ5O9CP2PMEP2OeT24wV65O5GUWIVyiTwUBSQPCWwmjxBbDrdkh@6B3KxDmW8JiG3FIvAHfwVUspaG89zFHB9Ag "Python 3 – TIO Nexus")
[Answer]
# [Bash](https://www.gnu.org/software/bash/), ~~66~~ ~~61~~ 49 bytes
```
case $1 in *$2)echo ${1%$2};;*)echo ${1#$2};;esac
```
[Try it online!](https://tio.run/nexus/bash#@5@cWJyqoGKokJmnoKVipJmanJGvoFJtqKpiVGttrQXnK4P5qcWJyf///09MSk5JBZIA "Bash – TIO Nexus")
less golfed:
```
a=$1;
case $1 in 
    *$2)  c=${a%$2};;       
    $2*)  c=${a#$2};;
      *)  c=$1;;
esac;
echo $c
```
Uses case to test begining or end, and array prefix/suffix (% / #) substraction
[Answer]
# [APL (Dyalog)](https://www.dyalog.com/), ~~31~~ 30 bytes
-1 thanks to  [Zacharý](https://codegolf.stackexchange.com/users/55550/zachar%c3%bd).
This actually uses reverse (i.e. the inverse of) concatenation! Takes original string as left argument, and what to subtract as right argument.
```
{0::⍺{0::⍺⋄,∘⍵⍣¯1⊢⍺}⍵⋄⍵,⍣¯1⊢⍺}
```
[Try it online!](https://tio.run/##SyzI0U2pTMzJT///P7g0qaQoMbnkUduEagMrq0e9u6DUo@4WnUcdMx71bn3Uu/jQesNHXYuAorUgfncLkNRBEf7/X11ZWTksMSczRQFmZGZ@npU6l3piUnJKqjpMEMjFFANxQIJAOQx1WMSwmpicAhRFNhKb1TCLUISBIigcoEc888qI8QoWwxITMcWSsDmmAltAVILdh@QAz7yC0hIrdQA "APL (Dyalog Unicode) – TIO Nexus")
Ungolfed:
```
{
    0::⍺{         ⍝ if an error happens, apply the following function on the arguments
        0::⍺          ⍝ if an error happens, return the left argument unmodified
        ,∘⍵⍣¯1⊢⍺      ⍝ inverse-append right argument on left argument
        }⍵
    ⍵,⍣¯1⊢⍺      ⍝ inverse-prepend the right argument on the left argument
}
```
Legend:
`{`…`}` anonymous function
`⍺` left argument of the current function
`⍵` right argument of the current function
`0::`… if any error happens, execute this, else…
`⍣¯1⊢` inverse
`,∘⍵` concatenate *⍵* on the right
`⍵,` concatenate *⍵* on the left
[Answer]
# PHP, 54 Bytes
```
[,$x,$y]=$argv;echo preg_replace("#^$y|$y$#","",$x,1);
```
[Testcases](http://sandbox.onlinephpfunctions.com/code/34d575ef526f172bb1b56d3f9b88dd5a6cab580f)
[Answer]
# [Python 2](https://docs.python.org/2/), 68 bytes
```
def f(s,c):v=len(c);print[s[v:],s[:-v],s][[s[:v],s[-v:],c].index(c)]
```
**[Try it online!](https://tio.run/nexus/python2#fZFNCsMgEIXXySmGQFBh0gNY2ouIi2Q0ECi2xCLp6VNNoe0iGReOvM/50bc6P8IoI5LS6XLzQZI6P@YpPE00SVuMRncpB2uyoMvJdEUne5qC80u@b9fxPkNEIJgCSCn6gZwXmKNQWMP/@sGy79GcdJzJQb4ruYy3tsxMn3jMd9C@@i3IVet7Bg7soAv7ta/yCKXrajMSmjZ708am3WxGEN1VYF0V14HU@gY "Python 2 – TIO Nexus")**
[Answer]
# [Haskell](https://www.haskell.org/), 49 bytes
```
f s a b|s==b=a|a/=b,h:t<-a=f(s++[h])t b|1<3=s
f""
```
[Try it online!](https://tio.run/nexus/haskell#bY3LCoMwEEX3fsWYVUKSPuhOnP5Bv8BmMdH6gCpiFGzx3632gbZ0M1zOPdzRmrRFHvVDH2oXU9XwQESGlJWyRyQj5dJd@ZnA6iNN0Jqn1ktpZ034/s7T@l7U/K/JyMbJhQm@/PigMQUHkz04RIs00BatyoM21IQpd9NCbkQ79fvwgM7LMGVsLKmoAKGk@gS8boqqhQ10Vdw1zQ0yARF/zadMzYEJBSsy328SJz/gHYRaMSbM@AA "Haskell – TIO Nexus") Usage: `f"" "abcdef" "ab"`. Alternatively, define `(-)=f""`and use like `"abcdef" - "ab"`.
This regex-free solution works by recursively splitting the string in all its pre- and postfixes and checking whether the string to be substracted matches one of them.
[Answer]
# [Python 2](https://docs.python.org/2/), ~~72~~ 65 bytes
```
a,b=input()
l=len(b)
print[[a,a[:-l]][b==a[-l:]],a[l:]][b==a[:l]]
```
[Try it online!](https://tio.run/nexus/python2#@5@ok2SbmVdQWqKhyZVjm5Oap5GkyVVQlJlXEh2dqJMYbaWbExsbnWRrmxitm2MVGwsUAlEQESug3P//6onJScnqOuqJSeoA "Python 2 – TIO Nexus")
-7 bytes thanks to @FelipeNardiBatista
[Answer]
# C#, 88 bytes
```
s=>r=>s.StartsWith(r)?s.Substring(r.Length):s.EndsWith(r)?s.Substring(0,s.IndexOf(r)):s;
```
Compiles to a `Func<string, Func<string, string>>`.
[Answer]
### Ruby (lambda expression), 29 bytes
```
->a,b{a.sub /^#{b}|#{b}$/,""}
```
Yay for regex interpolation! Requires regex-safe subtrahends, but that's okay as per the challenge.
[Answer]
# [Tcl](http://www.tcl.tk/), 37 bytes
```
proc s {a b} {regsub "^$b|$b$" $a {}}
```
[Try it online!](https://tio.run/nexus/tcl#ZZB9bsMgDMX/zymeIg6wC/QkVSfxYVKkNImASJsYZ88caEuySQjMz89@lrfFzxoBSUJlJE9DWBX6T6F@hBI9hETKuesCRUQKkZUdWK20IUgFfnIDFT4BZ8t55etfH/LPHiWoUBuOuQ32KB@d9nuf5I1SPhTypxyetNXQsXNF8h/a/f6yr/NQhX2bdzs2sbMnqe9lJRBtMaMMwQ1TRXi4aaXJgFcavbzvoXHWkqdJE6udRbqG6N00QM@PRXrCNUC86kQrvEG00hsuF3zk4ggsK5v3CzuTqcY98wwaA50kVrrxJOnytv0C) (now running all tests)
Tcl is straightforward. `proc s {a b}` defines a function named `s` which takes parameters `a` and `b`. `regsub` substitutes `{}`, which is an empty string, for the value of `b` when it's at the start or end of `a`. The return is implicit.
[Answer]
# C, 96 bytes
It's common knowledge that string manipulation in C is cumbersome, as an extension golfing would be borderline masochistic. Sounds alright to me.
```
f(a,b,t,l)char**a,*b,*t;{t=*a;l=strlen(b);bcmp(t,b,l)?bcmp(t+=strlen(t)-l,b,l)||(*t=0):(*a+=l);}
```
One of the less readable programs I've written. Takes two inputs (despite how the function looks), a `char**` pointing to the string to deconcatenate and a `char*` which is the string to remove. The input pointer is edited in place and becomes the output (who cases about memory leaks anyway).
Example usage:
```
char *a = malloc(6);
strcpy(a, "abcde");
char *b = malloc(4);
strcpy(b, "abc");
f(&a,b);
printf("%s\n", a); // "de"
```
[Answer]
# [AWK](https://www.gnu.org/software/gawk/manual/gawk.html), ~~21~~ 32 bytes
```
{sub("^"$2"|"$2"$",z,$1);$0=$1}1
```
[Try it online!](https://tio.run/nexus/awk#@19dXJqkoRSnpGKkVAMiVJR0qnRUDDWtVQxsVQxrDf//T0xKTklVSEzigjCAGMhKTIKKwBgIVckpQCZQGRdMCKIDxFYAAA "AWK – TIO Nexus")
Original submission naively replaced text within first string, not just at beginning or end.
```
{sub($2,z,$1);$0=$1}1
```
[Try it online !](https://tio.run/nexus/awk#@19dXJqkoWKkU6WjYqhprWJgq2JYa/j/f2JSckqqQmISF4QBxEBWYhJUBMZAqEpOATKByrhgQhAdILYCAA "AWK – TIO Nexus")
Originally tried without the braces, but it required tricks to print out empty lines and or no-matches which ended up adding more bytes than this version.
[Answer]
# R, ~~20~~ ~~42~~ 41 bytes
```
pryr::f(sub(sprintf('^%s|%s$',b,b),'',a))
```
*-1 byte thanks to MickyT!*
Returns an anonymous function (which has arguments in the order `b,a`). Computes the string difference `a-b`. `sub` is a simple substitution that swaps the first occurrence of the pattern with, in this case, the empty string `''`. Constructs the regex with `sprintf` to match only at the beginning and end of string. Requires the `pryr` package to be installed.
On the TIO link, uses the more verbose `function(a,b)` definition for the function for four more bytes.
[Try it online!](https://tio.run/nexus/r#DcnBCcAwCAXQZRq@git0lYIKgVxsqcmtu9tc3@tn9RU@xx2kYpzLKJ93xOyEq@XX8oDYHgFEuTaruRoEruD6AQ)
[Answer]
# Common Lisp, 121 bytes
```
(lambda(x y)(cond((equal(#1=subseq x 0 #3=(length y))y)(#1#x #3#))((equal(#1#x #2=(-(length x)#3#))y)(#1#x 0 #2#))(t x)))
```
[Try it online!](https://tio.run/##ZZDLDoIwEEXX8hU3bQwziSY@1vgvhdZHglQFE9jw6zotPhBZzNDT0zvJFOWpvjyo9P6Cvb@BWnSMU4WUSJm8sE5BugIj@YJYXyRc/hhT8J9SWEExRkgynjMOHthgfH4@qpucze85n2a3cfwIdKHOmJMZhs96kKzgbBo0UGlv0kUoWO4Qej9XkOWAZFvmnFsTV0WFryyRu95NSXqd1fe8dlcRV9DbjEpXHZqjeCyqXutWqGb@Pghkk9HybbYchbctKZvgN3LB/AgTpT0B)
The usual wordy Common Lisp!
Ungolfed version:
```
(defun f(x y)
  (cond ((equal (subseq x 0 (length y)) y)               ; if x starts with y
         (subseq x (length y)))                          ; return rest of x
        ((equal (subseq x (- (length x) (length y))) y)  ; if x ends with x
         (subseq x 0 (- (length x) (length y))))         ; return first part of x
        (t x)))                                          ; else return x
```
[Answer]
# [Kotlin](https://kotlinlang.org), 91 bytes
```
{a,b->val v=b.length
if(a.startsWith(b))a.drop(v)else if(a.endsWith(b))a.dropLast(v)else a}
```
[Try it online!](https://tio.run/##dY@xDoIwEIb3PsWFqU2AByCCcXNgc3C@pgUaayFtwRjCs9cK4mDiDXd/8v3Dd7fea2VCMxq4ozIUbesKOFmLz8PFW2XaisFMIM6EGtzIC6AbSGG7DLLqE6EMM6Y8q97dqeS5lqb1HVENxdx5tN5dle8oZwxzYfuBTkxqJ2EtSCN@cI3O7xVcwm6BUIKVKGplJGVwLCBJvor8HxyioafxAxoVGSNLOEute3j0Vguy7hc "Kotlin – Try It Online")
[Answer]
# Powershell, ~~34~~ 40 bytes
*+6 bytes when `Invalid Subtraction` test cases added*
```
param($s,$t)$s-replace"^$t(?!.*$t$)|$t$"
```
Comment:
The regexp expression `^$t|$t$` does not work as expected: it replaces both matches instead one (flag `g` always on). So, we are forced to use the negative lookahead group.
Test script:
```
$f = {
    param($s,$t)$s-replace"^$t(?!.*$t$)|$t$"
}
@(
    ,('abcde','ab', 'cde')
    ,('abcde','cde', 'ab')
    ,('abab','ab', 'ab')
    ,('abcab','ab', 'abc', 'cab')
    ,('ababcde','ab', 'abcde')
    ,('acdbcd','cd', 'acdb')
    ,('abcde','abcde', '')
    ,('abcde','', 'abcde')
    ,('','', '')
    ,('abcde','ae', 'abcde')
    ,('abcde','aa', 'abcde')
    ,('abcde','bcd', 'abcde')
    ,('abcde','xab', 'abcde')
    ,('abcde','yde', 'abcde')
    ,('','a', '')
) | % {
    $s,$t,$e = $_
    $r = &$f $s $t
    "$($r-in$e): $r"
}
```
Output:
```
True: cde
True: ab
True: ab
True: abc
True: abcde
True: acdb
True:
True: abcde
True:
```
[Answer]
## [QBIC](https://drive.google.com/drive/folders/0B0R1Jgqp8Gg4cVJCZkRkdEthZDQ), 57 bytes
Whegh, this is a mess in QBIC/QBasic...
```
B=@ `+B┘x=instr(;,;)~x|?_t_sB,x-1|+_sB,x+_lC|,_lB|||\?B
B=@ `+B          Prepend a string to B$. Thisis a hack to avoid errors with 
                 removing substrings stating at index 1
┘                Line-break in QBasic output
       (;,;)     Read the string (B$) and the to-be-removed substring (C$)
x=instr          And make x to be the starting index of the first C$ in B$
~x|              IF X <> 0 (ie C$ is present in B$)
?                PRINT
 _t                trimmed version (drops the prepended space)
  _sB,x-1|+        of a substring from 1 to x (the start of C$) -1
  _sB,x+_lC|,_lB   and the rest of the string, starting after C$
                     _l takes the length of a string
  |||              End TRIM, end Substring, end Length
\?B              When missing C$, just print B$
```
[Answer]
# [Lua](https://www.lua.org), ~~71~~ 65 bytes
Accepting suggestions
```
a,b=...p='(.*)'print(a:match('^'..b..p)or a:match(p..b..'$')or a)
```
[Try it online!](https://tio.run/nexus/lua#@5@ok2Srp6dXYKuuoaelqV5QlJlXopFolZtYkpyhoR6nrqeXBJTVzC9SgAkWgIXUVdTBgpr///9PTEpOTAKSAA "Lua – TIO Nexus")
[Answer]
I initially misread the instructions. Thanks, [Ørjan Johansen](https://codegolf.stackexchange.com/users/66041/%C3%98rjan-johansen) for pointing out my mistake!
# [PowerShell](https://github.com/TryItOnline/TioSetup/wiki/Powershell), 46 51 bytes
```
Function F($o,$a){([regex]"^$a").replace($o,'',1);}
```
[Try it online!](https://tio.run/nexus/powershell#@@9Wmpdckpmfp@CmoZKvo5KoWa0RXZSanloRqxSnkqikqVeUWpCTmJwKklVX1zHUtK79/x8A "PowerShell – TIO Nexus")
[Answer]
# Excel, 129 bytes
```
=IFERROR(IF(FIND(B1,A1)=1,SUBSTITUTE(A1,B1,"",1),IF(FIND(B1,A1,LEN(A1)-LEN(B1))>LEN(A1)-LEN(B1),LEFT(A1,LEN(A1)-LEN(B1)),A1)),A1)
```
[Answer]
# [sed](https://www.gnu.org/software/sed/), ~~56~~ 53 bytes
```
s/^(.*),(.*)\1$/\2/
s/^(.*),\1(.*)$/\2/
s/.*,(.*)/\1/
```
[Try it online!](https://tio.run/##K05N0U3PK/3/v1g/TkNPS1MHRMQYqujHGOlzwcRiDEEUTExPC6xIP8ZQ////xCSdxKTklNR/@QUlmfl5xf91iwA "sed – Try It Online")
]