6139
|
1 ## Copyright (C) 1996, 2006 Kurt Hornik |
2325
|
2 ## |
2313
|
3 ## This file is part of Octave. |
|
4 ## |
|
5 ## Octave is free software; you can redistribute it and/or modify it |
|
6 ## under the terms of the GNU General Public License as published by |
|
7 ## the Free Software Foundation; either version 2, or (at your option) |
|
8 ## any later version. |
|
9 ## |
|
10 ## Octave is distributed in the hope that it will be useful, but |
|
11 ## WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
13 ## General Public License for more details. |
|
14 ## |
|
15 ## You should have received a copy of the GNU General Public License |
|
16 ## along with Octave; see the file COPYING. If not, write to the Free |
5307
|
17 ## Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
|
18 ## 02110-1301, USA. |
2271
|
19 |
3361
|
20 ## -*- texinfo -*- |
|
21 ## @deftypefn {Function File} {} index (@var{s}, @var{t}) |
6139
|
22 ## @deftypefnx {Function File} {} index (@var{s}, @var{t}, @var{direction}) |
3361
|
23 ## Return the position of the first occurrence of the string @var{t} in the |
|
24 ## string @var{s}, or 0 if no occurrence is found. For example, |
3426
|
25 ## |
3361
|
26 ## @example |
|
27 ## index ("Teststring", "t") |
|
28 ## @result{} 4 |
|
29 ## @end example |
3426
|
30 ## |
6139
|
31 ## If @var{direction} is @samp{"first"}, return the first element found. |
|
32 ## If @var{direction} is @samp{"last"}, return the last element found. |
|
33 ## The @code{rindex} function is equivalent to @code{index} with |
|
34 ## @var{direction} set to @samp{"last"}. |
|
35 ## |
|
36 ## @strong{Caution:} This function does not work for arrays of |
|
37 ## character strings. |
|
38 ## @seealso{find, rindex} |
3361
|
39 ## @end deftypefn |
2271
|
40 |
5428
|
41 ## Author: Kurt Hornik <Kurt.Hornik@wu-wien.ac.at> |
2355
|
42 ## Adapted-By: jwe |
2314
|
43 |
6139
|
44 function n = index (s, t, direction) |
2271
|
45 |
2303
|
46 ## This is patterned after the AWK function of the same name. |
2271
|
47 |
6139
|
48 if (nargin < 2 || nargin > 3) |
6046
|
49 print_usage (); |
6139
|
50 elseif (nargin < 3) |
|
51 direction = "first"; |
2271
|
52 endif |
6139
|
53 direction = lower (direction); |
|
54 |
|
55 if (! (ischar (s) && ischar (t) && isvector (s) && isvector (t))) |
|
56 error ("index: expecting character string arguments"); |
|
57 elseif (! strcmp (direction, {"first", "last"})) |
|
58 error ("index: direction must be either \"first\" or \"last\""); |
2271
|
59 endif |
2325
|
60 |
3911
|
61 l_s = length (s); |
|
62 l_t = length (t); |
6139
|
63 |
|
64 n = 0; |
|
65 if (l_s == 0 || l_s < l_t) |
3911
|
66 ## zero length source, or target longer than source |
6139
|
67 ## return 0 |
3911
|
68 v = []; |
6139
|
69 |
|
70 elseif (l_t == 0) |
3911
|
71 ## zero length target: return first |
|
72 v = 1; |
6139
|
73 |
|
74 elseif (l_t == 1) |
3911
|
75 ## length one target: simple find |
6139
|
76 v = find (s==t, 1, direction); |
|
77 |
|
78 elseif (l_t == 2) |
3911
|
79 ## length two target: find first at i and second at i+1 |
6139
|
80 v = find (s (1:l_s-1) == t(1) & s(2:l_s) == t(2), 1, direction); |
|
81 |
3911
|
82 else |
|
83 ## length three or more: match the first three by find then go through |
|
84 ## the much smaller list to determine which of them are real matches |
|
85 limit = l_s - l_t + 1; |
6139
|
86 v = find (s (1:limit) == t(1) |
|
87 & s (2:limit+1) == t(2) |
|
88 & s (3:limit+2) == t(3)); |
|
89 if (strcmp (direction, "last")) |
|
90 v = v(length(v):-1:1); |
3911
|
91 endif |
6139
|
92 |
|
93 if (l_t > 3) |
|
94 |
|
95 ## force strings to be both row vectors or both column vectors |
|
96 if (all (size (s) != size (t))) |
|
97 t = t.'; |
3911
|
98 endif |
|
99 |
6139
|
100 ## search index vector for a match |
|
101 ind = 0:l_t-1; |
|
102 ## return 0 if loop terminates without finding any match |
|
103 for idx = 1:length(v) |
|
104 if (s (v(idx) + ind) == t) |
|
105 n = v(idx); |
|
106 break; |
|
107 endif |
|
108 endfor |
|
109 endif |
3911
|
110 |
|
111 endif |
|
112 |
6139
|
113 if (n == 0 && ! isempty (v)) |
|
114 ## return the first found if n is not already set and v is not empty |
|
115 n = v(1); |
|
116 endif |
|
117 |
2271
|
118 endfunction |
6139
|
119 |
|
120 ## Test the function out |
|
121 %!assert(index("astringbstringcstring", "s"), 2) |
|
122 %!assert(index("astringbstringcstring", "st"), 2) |
|
123 %!assert(index("astringbstringcstring", "str"), 2) |
|
124 %!assert(index("astringbstringcstring", "string"), 2) |
|
125 |
|
126 ## test everything out in reverse |
|
127 %!assert(index("astringbstringcstring", "s", "last"), 16) |
|
128 %!assert(index("astringbstringcstring", "st", "last"), 16) |
|
129 %!assert(index("astringbstringcstring", "str", "last"), 16) |
|
130 %!assert(index("astringbstringcstring", "string", "last"), 16) |