1######################################################################## 2## 3## Copyright (C) 1996-2021 The Octave Project Developers 4## 5## See the file COPYRIGHT.md in the top-level directory of this 6## distribution or <https://octave.org/copyright/>. 7## 8## This file is part of Octave. 9## 10## Octave is free software: you can redistribute it and/or modify it 11## under the terms of the GNU General Public License as published by 12## the Free Software Foundation, either version 3 of the License, or 13## (at your option) any later version. 14## 15## Octave is distributed in the hope that it will be useful, but 16## WITHOUT ANY WARRANTY; without even the implied warranty of 17## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18## GNU General Public License for more details. 19## 20## You should have received a copy of the GNU General Public License 21## along with Octave; see the file COPYING. If not, see 22## <https://www.gnu.org/licenses/>. 23## 24######################################################################## 25 26## -*- texinfo -*- 27## @deftypefn {} {} substr (@var{s}, @var{offset}) 28## @deftypefnx {} {} substr (@var{s}, @var{offset}, @var{len}) 29## Return the substring of @var{s} which starts at character number 30## @var{offset} and is @var{len} characters long. 31## 32## Position numbering for offsets begins with 1. If @var{offset} is negative, 33## extraction starts that far from the end of the string. 34## 35## If @var{len} is omitted, the substring extends to the end of @var{s}. A 36## negative value for @var{len} extracts to within @var{len} characters of 37## the end of the string 38## 39## Examples: 40## 41## @example 42## @group 43## substr ("This is a test string", 6, 9) 44## @result{} "is a test" 45## substr ("This is a test string", -11) 46## @result{} "test string" 47## substr ("This is a test string", -11, -7) 48## @result{} "test" 49## @end group 50## @end example 51## 52## This function is patterned after the equivalent function in Perl. 53## @end deftypefn 54 55function t = substr (s, offset, len) 56 57 if (nargin < 2 || nargin > 3) 58 print_usage (); 59 endif 60 61 if (! ischar (s)) 62 error ("substr: S must be a string or string array"); 63 elseif (! isscalar (offset) || (nargin == 3 && ! isscalar (len))) 64 error ("substr: OFFSET and LEN must be scalar integers"); 65 endif 66 67 offset = fix (offset); 68 nc = columns (s); 69 if (abs (offset) > nc || offset == 0) 70 error ("substr: OFFSET = %d out of range", offset); 71 endif 72 73 if (offset <= 0) 74 offset += nc + 1; 75 endif 76 77 if (nargin == 2) 78 eos = nc; 79 else 80 len = fix (len); 81 if (len < 0) 82 eos = nc + len; 83 else 84 eos = offset + len - 1; 85 endif 86 endif 87 88 if (eos > nc) 89 error ("substr: length LEN = %d out of range", len); 90 elseif (offset > eos && len != 0) 91 error ("substr: No overlap with chosen values of OFFSET and LEN"); 92 endif 93 94 t = s(:, offset:eos); 95 96endfunction 97 98 99%!assert (substr ("This is a test string", 6, 9), "is a test") 100%!assert (substr ("This is a test string", -11), "test string") 101%!assert (substr ("This is a test string", -11, 4), "test") 102%!assert (substr ("This is a test string", -11, -7), "test") 103%!assert (substr ("This is a test string", 1, -7), "This is a test") 104%!assert (isempty (substr ("This is a test string", 1, 0))) 105 106## Test input validation 107%!error substr () 108%!error substr ("foo", 2, 3, 4) 109%!error substr (ones (5, 1), 1, 1) 110%!error substr ("foo", ones (2,2)) 111%!error substr ("foo", 1, ones (2,2)) 112%!error substr ("foo", 0) 113%!error substr ("foo", 5) 114%!error substr ("foo", 1, 5) 115%!error substr ("foo", -1, 5) 116%!error substr ("foo", 2, -5) 117