function s = extractBetween(str, start, stop, varargin)
% EXTRACTBETWEEN Extract substring from text
%    S = EXTRACTBETWEEN(STR, START_PAT, END_PAT) returns the substring of
%    STR that occurs between START_PAT and END_PAT but does not include
%    either START_PAT and END_PAT. If multiple nonoverlapping START_PAT
%    END_PAT pairs are found in STR, S grows along the first trailing
%    dimension whose size is 1 and the text between each pair is returned.
% 
%    S = EXTRACTBETWEEN(STR, START_POS, END_POS) returns a substring of STR
%    that starts at numeric position START_POS and ends at numeric position
%    END_POS. START_POS and END_POS must be integers between 1 and the
%    number of characters in STR. The substring S includes the characters
%    at those positions. If START_POS and END_POS are the same number, then
%    S contains the character at START_POS. If END_POS equals START_POS - 1,
%    then S is the empty string.
% 
%    NOTES:
%    * STR must be text, which means it can be a string array, a character 
%      vector, or a cell array of character vectors. START_PAT and END_PAT
%      must be text or a pattern array. If STR is a string array, then so 
%      is the output S. Otherwise, S is a cell array of character vectors.
%
%    * START_PAT and END_PAT are an open set (i.e., bounds
%      are not included in the output) while the START_POS and END_POS
%      numeric positions are a closed set (i.e., bounds are included in the
%      output).
% 
%    * Position, text, and pattern bounds can be mixed. Their inclusivity persists
%      with the argument type.
%
%    S = EXTRACTBETWEEN(..., 'Boundaries', B) forces the bounds to be
%    inclusive when B is 'inclusive' and forces the bounds to be exclusive
%    when B is 'exclusive'.
%
%    If B is 'exclusive' and you specify numeric bounds, then START_POS and
%    END_POS can be integers between 0 and strlength(STR) + 1.
%
%    Examples:
%        STR = "The quick brown fox";
%        START_PAT = 'quick';
%        END_PAT = 'fox';
%        extractBetween(STR,START_PAT,END_PAT)
%
%        % returns " brown "
%
%        STR = 'The quick brown fox jumps over the lazy dog';
%        START_PAT = 'quick';
%        END_PAT = 'fox';
%        extractBetween(STR,START_PAT,END_PAT,'Boundaries','inclusive')
%
%        % returns {'quick brown fox'}
%
%        STR = 'The quick brown fox jumps over the lazy dog';
%        START_PAT = textBoundary + lettersPattern + " ";
%        END_PAT = lettersPattern + textBoundary;
%        eraseBetween(STR,START_PAT,END_PAT) 
%
%        % returns 'The dog'
%
%    See also ERASEBETWEEN, REPLACEBETWEEN, EXTRACTBEFORE, EXTRACTAFTER, PATTERN

%   Copyright 2016-2020 The MathWorks, Inc.

    narginchk(3, Inf);
    if ~isTextStrict(str)
        firstInput = getString(message('MATLAB:string:FirstInput'));
        error(message('MATLAB:string:MustBeCharCellArrayOrString', firstInput));
    end

    try
        s = string(str);
        s = s.extractBetween(start, stop, varargin{:});
        
        if ~isstring(str)
            s = cellstr(s);
        end
        
    catch E
        throw(E);
    end
end
