Mercurial > octave
view scripts/strings/endsWith.m @ 28232:49384057fb03
endsWith.m: overhaul function.
* endsWith.m: Use @group within @example blocks in documentation. Clarify
docstring text. Add regexp, strncmp, strncmpi to @seealso reference.
Combine input validation in to smaller code blocks. Eliminate try/catch
block by using isreal() test. Use cellfun() rather than for loop with flip()
to reverse STR and PATTERN. Declare retval to be of logical type rather
than double type. Update BIST tests.
author | Rik <rik@octave.org> |
---|---|
date | Mon, 20 Apr 2020 08:28:22 -0700 |
parents | d052c11d47c6 |
children | a6edb8097ec6 |
line wrap: on
line source
######################################################################## ## ## Copyright (C) 2020 The Octave Project Developers ## ## See the file COPYRIGHT.md in the top-level directory of this ## distribution or <https://octave.org/copyright/>. ## ## This file is part of Octave. ## ## Octave is free software: you can redistribute it and/or modify it ## under the terms of the GNU General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Octave is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with Octave; see the file COPYING. If not, see ## <https://www.gnu.org/licenses/>. ## ######################################################################## ## -*- texinfo -*- ## @deftypefn {} {@var{retval} =} endsWith (@var{str}, @var{pattern}) ## @deftypefnx {} {@var{retval} =} endsWith (@var{str}, @var{pattern}, "IgnoreCase", @var{confirm_ignore}) ## @deftypefnx {} {@var{retval} =} endsWith (@var{str}, @var{pattern}, "IgnoreCase", @var{ignore_case}) ## Check whether string(s) end with pattern(s). ## ## Return an array of logical values that indicates which string(s) in the ## input @var{str} (a single string or cell array of strings) end with ## the input @var{pattern} (a single string or cell array of strings). ## ## If the value of the parameter @qcode{"IgnoreCase"} is true, then the ## function will ignore the letter case of @var{str} and @var{pattern}. By ## default, the comparison is case sensitive. ## ## Examples: ## ## @example ## @group ## ## one string and one pattern while considering case ## endsWith ("hello", "lo") ## @result{} 1 ## @end group ## ## @group ## ## one string and one pattern while ignoring case ## endsWith ("hello", "LO", "IgnoreCase", true) ## @result{} 1 ## @end group ## ## @group ## ## multiple strings and multiple patterns while considering case ## endsWith (@{"tests.txt", "mydoc.odt", "myFunc.m", "results.pptx"@}, ## @{".docx", ".odt", ".txt"@}) ## @result{} 1 1 0 0 ## @end group ## ## @group ## ## multiple strings and one pattern while considering case ## endsWith (@{"TESTS.TXT", "mydoc.odt", "result.txt", "myFunc.m"@}, ## ".txt", "IgnoreCase", false) ## @result{} 0 0 1 0 ## @end group ## ## @group ## ## multiple strings and one pattern while ignoring case ## endsWith (@{"TESTS.TXT", "mydoc.odt", "result.txt", "myFunc.m"@}, ## ".txt", "IgnoreCase", true) ## @result{} 1 0 1 0 ## @end group ## @end example ## ## @seealso{startsWith, regexp, strncmp, strncmpi} ## @end deftypefn function retval = endsWith (str, pattern, IgnoreCase, ignore_case) if (nargin != 2 && nargin != 4) print_usage (); endif ## Validate input str and pattern if (! (iscellstr (str) || ischar (str))) error ("endsWith: STR must be a string or cell array of strings"); endif if (! (iscellstr (pattern) || ischar (pattern))) error ("endsWith: PATTERN must be a string or cell array of strings"); endif ## reverse str and pattern str = cellfun (@flip, cellstr (str), "UniformOutput", false); pattern = cellfun (@flip, cellstr (pattern), "UniformOutput", false); if (nargin == 2) ignore_case = false; else ## For Matlab compatibility accept any abbreviation of 3rd argument if (! ischar (IgnoreCase) || isempty (IgnoreCase) || ! strncmpi (IgnoreCase, "IgnoreCase", length (IgnoreCase))) error ('endsWith: third input must be "IgnoreCase"'); endif if (! isscalar (ignore_case) || ! isreal (ignore_case)) error ('endsWith: "IgnoreCase" value must be a logical scalar'); endif ignore_case = logical (ignore_case); endif retval = false (size (str)); if (ignore_case) for j = 1:numel (pattern) retval |= strncmpi (str, pattern{j}, length (pattern{j})); endfor else for j = 1:numel (pattern) retval |= strncmp (str, pattern{j}, length (pattern{j})); endfor endif endfunction ## Test simple use with one string and one pattern %!assert (endsWith ("hello", "lo")) %!assert (! endsWith ("hello", "LO")) %!assert (endsWith ("hello", "LO", "i", 5)) %!assert (! endsWith ("hello", "no")) ## Test multiple strings with a single pattern %!test %! str = {"myFile.odt", "results.ppt", "myCode.m"; ... %! "data-analysis.ppt", "foundations.txt", "data.odt"}; %! pattern = ".odt"; %! expected = [true, false, false; false, false, true]; %! assert (endsWith (str, pattern), expected); ## Test multiple strings with multiple patterns %!test %! str = {"tests.txt", "mydoc.odt", "myFunc.m", "results.pptx"}; %! pattern = {".docx", ".odt", ".txt"}; %! expected = [true, true, false, false]; %! assert (endsWith (str, pattern), expected); ## Test IgnoreCase %!test %! str = {"TESTS.TXT", "mydoc.odt", "result.txt", "myFunc.m"}; %! pattern = ".txt"; %! expected_ignore = [true, false, true, false]; %! expected_wo_ignore = [false, false, true, false]; %! assert (endsWith (str, pattern, "IgnoreCase", true), expected_ignore); %! assert (endsWith (str, pattern, "IgnoreCase", false), expected_wo_ignore); %! assert (endsWith (str, pattern, "I", 500), expected_ignore); %! assert (endsWith (str, pattern, "iG", 0), expected_wo_ignore); ## Test input validation %!error endsWith () %!error endsWith ("A") %!error endsWith ("A", "B", "C") %!error endsWith ("A", "B", "C", "D", "E") %!error <STR must be a string> endsWith (152, "hi") %!error <STR must be a .* cell array of strings> endsWith ({152}, "hi") %!error <PATTERN must be a string> endsWith ("hi", 152) %!error <PATTERN must be a .* cell array of strings> endsWith ("hi", {152}) %!error <third input must be "IgnoreCase"> endsWith ("hello", "lo", 1, 1) %!error <third input must be "IgnoreCase"> endsWith ("hello", "lo", "", 1) %!error <third input must be "IgnoreCase"> endsWith ("hello", "lo", "foo", 1) %!error <"IgnoreCase" value must be a logical scalar> %! endsWith ("hello", "hi", "i", "true"); %!error <"IgnoreCase" value must be a logical scalar> %! endsWith ("hello", "hi", "i", {true});